mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-27 02:43:07 +00:00
+ Lots of cleanup after the sessionstore transplant
+ Now saving pageBounds. + Removed some unnecessary save calls and added some necessary ones + Added a reset command to the dev menu; wipes storage and refreshes + Fixed the save command on the dev menu so it now works again + Reconnected storage sanity checks + Removed a bunch of now unused storage code + Fixed a problem with cold start + Removed a bunch of logging code + Pulled BrowserWatcher out of tabs.js + Added a direct link to the code documentation to the dev menu
This commit is contained in:
parent
e92aca399e
commit
987baafa7c
117
browser/base/content/tabcandy/app/browserwatcher.js
Normal file
117
browser/base/content/tabcandy/app/browserwatcher.js
Normal file
@ -0,0 +1,117 @@
|
||||
// Title: browserwatcher.js
|
||||
(function(){
|
||||
|
||||
Utils.log('warning! browserwatcher.js has not been tested since the code was taken from tabs.js!');
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
// ##########
|
||||
// Class: WindowWatcher
|
||||
function WindowWatcher() {
|
||||
var self = this;
|
||||
|
||||
var observer = {
|
||||
observe: function(window, event) {
|
||||
if (event == "domwindowopened") {
|
||||
if (self.onWindowOpened)
|
||||
self.onWindowOpened(window);
|
||||
} else
|
||||
if (self.onWindowClosed)
|
||||
self.onWindowClosed(window);
|
||||
}
|
||||
};
|
||||
|
||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Ci.nsIWindowWatcher);
|
||||
ww.registerNotification(observer);
|
||||
|
||||
Extension.addUnloadMethod(
|
||||
this,
|
||||
function() {
|
||||
ww.unregisterNotification(observer);
|
||||
});
|
||||
}
|
||||
|
||||
// ##########
|
||||
// Class: BrowserWatcher
|
||||
// When this object is instantiated, the given onLoad() is called for
|
||||
// all browser windows, and subsequently for all newly-opened browser
|
||||
// windows. When a browser window closes, onUnload() is called.
|
||||
// onUnload() is also called once for each browser window when the
|
||||
// extension is unloaded.
|
||||
function BrowserWatcher(options) {
|
||||
var pendingHandlers = [];
|
||||
|
||||
function makeSafeFunc(func) {
|
||||
function safeFunc(window) {
|
||||
try {
|
||||
func(window);
|
||||
} catch (e) {
|
||||
Utils.log(e);
|
||||
}
|
||||
};
|
||||
return safeFunc;
|
||||
}
|
||||
|
||||
function addUnloader(chromeWindow, func) {
|
||||
function onUnload() {
|
||||
chromeWindow.removeEventListener("unload", onUnload, false);
|
||||
pendingHandlers.splice(pendingHandlers.indexOf(onUnload), 1);
|
||||
func(chromeWindow);
|
||||
}
|
||||
pendingHandlers.push(onUnload);
|
||||
chromeWindow.addEventListener("unload", onUnload, false);
|
||||
}
|
||||
|
||||
function loadAndBind(chromeWindow) {
|
||||
if (options.onLoad)
|
||||
(makeSafeFunc(options.onLoad))(chromeWindow);
|
||||
if (options.onUnload)
|
||||
addUnloader(chromeWindow, makeSafeFunc(options.onUnload));
|
||||
}
|
||||
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Ci.nsIWindowMediator);
|
||||
|
||||
var enumerator = wm.getEnumerator(XULApp.appWindowType);
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var chromeWindow = enumerator.getNext();
|
||||
if (chromeWindow.gIsDoneLoading)
|
||||
loadAndBind(chromeWindow);
|
||||
else
|
||||
onWindowOpened(chromeWindow);
|
||||
}
|
||||
|
||||
function onWindowOpened(chromeWindow) {
|
||||
function removeListener() {
|
||||
chromeWindow.removeEventListener("load", onLoad, false);
|
||||
pendingHandlers.splice(pendingHandlers.indexOf(removeListener), 1);
|
||||
}
|
||||
function onLoad() {
|
||||
removeListener();
|
||||
var type = chromeWindow.document.documentElement
|
||||
.getAttribute("windowtype");
|
||||
if (type == XULApp.appWindowType)
|
||||
loadAndBind(chromeWindow);
|
||||
}
|
||||
chromeWindow.addEventListener("load", onLoad, false);
|
||||
pendingHandlers.push(removeListener);
|
||||
}
|
||||
|
||||
var ww = new WindowWatcher();
|
||||
ww.onWindowOpened = onWindowOpened;
|
||||
|
||||
Extension.addUnloadMethod(
|
||||
this,
|
||||
function() {
|
||||
ww.unload();
|
||||
var handlers = pendingHandlers.slice();
|
||||
handlers.forEach(function(handler) { handler(); });
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
@ -162,6 +162,8 @@ window.Group = function(listOfEls, options) {
|
||||
});
|
||||
} else
|
||||
self.adjustTitleSize();
|
||||
|
||||
self.save();
|
||||
}
|
||||
|
||||
this.$title
|
||||
@ -276,9 +278,10 @@ window.Group.prototype = $.extend(new Item(), new Subscribable(), {
|
||||
save: function() {
|
||||
if (!this._inited) // too soon to save now
|
||||
return;
|
||||
|
||||
var data = this.getStorageData();
|
||||
/* Utils.log("data to save: " + data.toSource()); */
|
||||
Storage.saveGroup(Utils.getCurrentWindow(), data);
|
||||
if(Groups.groupStorageSanity(data))
|
||||
Storage.saveGroup(Utils.getCurrentWindow(), data);
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -300,7 +303,6 @@ window.Group.prototype = $.extend(new Item(), new Subscribable(), {
|
||||
var css = {width: w};
|
||||
this.$title.css(css);
|
||||
this.$titleShield.css(css);
|
||||
this.save();
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -554,15 +556,13 @@ window.Group.prototype = $.extend(new Item(), new Subscribable(), {
|
||||
self.remove($el);
|
||||
});
|
||||
|
||||
item.parent = this;
|
||||
item.setParent(this);
|
||||
|
||||
if(typeof(item.setResizable) == 'function')
|
||||
item.setResizable(false);
|
||||
|
||||
if(item.tab == Utils.activeTab)
|
||||
Groups.setActiveGroup(this);
|
||||
|
||||
item.save();
|
||||
}
|
||||
|
||||
if(!options.dontArrange)
|
||||
@ -601,7 +601,7 @@ window.Group.prototype = $.extend(new Item(), new Subscribable(), {
|
||||
if(index != -1)
|
||||
this._children.splice(index, 1);
|
||||
|
||||
item.parent = null;
|
||||
item.setParent(null);
|
||||
item.removeClass("tabInGroup");
|
||||
item.removeClass("stacked");
|
||||
item.removeClass("stack-trayed");
|
||||
@ -627,7 +627,6 @@ window.Group.prototype = $.extend(new Item(), new Subscribable(), {
|
||||
var toRemove = $.merge([], this._children);
|
||||
$.each(toRemove, function(index, child) {
|
||||
self.remove(child, {dontArrange: true});
|
||||
child.save();
|
||||
});
|
||||
},
|
||||
|
||||
@ -861,8 +860,6 @@ window.Group.prototype = $.extend(new Item(), new Subscribable(), {
|
||||
|
||||
this.arrange({z: z + 2});
|
||||
}
|
||||
|
||||
this.save();
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -931,8 +928,6 @@ window.Group.prototype = $.extend(new Item(), new Subscribable(), {
|
||||
this.$resizer.fadeOut();
|
||||
$(this.container).resizable('disable');
|
||||
}
|
||||
|
||||
this.save();
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -994,8 +989,6 @@ window.Group.prototype = $.extend(new Item(), new Subscribable(), {
|
||||
// actions is necessary for a good user experience.
|
||||
|
||||
self.onNextNewTab(doNextTab);
|
||||
|
||||
this.save();
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -1283,13 +1276,14 @@ window.Groups = {
|
||||
init: function() {
|
||||
this.groups = [];
|
||||
this.nextID = 1;
|
||||
this._inited = false;
|
||||
},
|
||||
|
||||
// ----------
|
||||
getNextID: function() {
|
||||
var result = this.nextID;
|
||||
this.nextID++;
|
||||
Storage.saveGroupsData(Utils.getCurrentWindow(), {nextID:this.nextID});
|
||||
this.save();
|
||||
return result;
|
||||
},
|
||||
|
||||
@ -1303,73 +1297,77 @@ window.Groups = {
|
||||
return data;
|
||||
},
|
||||
|
||||
// ----------
|
||||
saveAll: function() {
|
||||
this.save();
|
||||
$.each(this.groups, function(index, group) {
|
||||
group.save();
|
||||
});
|
||||
},
|
||||
|
||||
// ----------
|
||||
save: function() {
|
||||
if (!this._inited) // too soon to save now
|
||||
return;
|
||||
|
||||
Storage.saveGroupsData(Utils.getCurrentWindow(), {nextID:this.nextID});
|
||||
},
|
||||
|
||||
// ----------
|
||||
reconstitute: function(groupsData, groupData) {
|
||||
try {
|
||||
/* Utils.log("in reconst"); */
|
||||
if(groupsData && groupsData.nextID)
|
||||
this.nextID = groupsData.nextID;
|
||||
else {
|
||||
// Decrement and increment. Increment will trigger a save, and that is
|
||||
// actually what we want here.
|
||||
--this.nextID;
|
||||
this.getNextID();
|
||||
}
|
||||
if(groupsData && groupsData.nextID)
|
||||
this.nextID = groupsData.nextID;
|
||||
|
||||
if(groupData) {
|
||||
for (var id in groupData) {
|
||||
/*
|
||||
Utils.log("id: " + id);
|
||||
Utils.log("groupData[id]: "+ groupData[id].toSource());
|
||||
*/
|
||||
var group = groupData[id];
|
||||
/* Utils.log("src: " +group.toSource()); */
|
||||
var isNewTabsGroup = (group.title == 'New Tabs');
|
||||
if(groupData) {
|
||||
for (var id in groupData) {
|
||||
var group = groupData[id];
|
||||
if(this.groupStorageSanity(group)) {
|
||||
var isNewTabsGroup = (group.title == 'New Tabs');
|
||||
var options = {
|
||||
locked: {
|
||||
close: isNewTabsGroup,
|
||||
title: isNewTabsGroup
|
||||
},
|
||||
dontPush: true
|
||||
};
|
||||
|
||||
new Group([], $.extend({}, group, options));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var group = this.getNewTabGroup();
|
||||
if(!group) {
|
||||
var box = this.getBoundsForNewTabGroup();
|
||||
var options = {
|
||||
locked: {
|
||||
close: isNewTabsGroup,
|
||||
title: isNewTabsGroup
|
||||
close: true,
|
||||
title: true
|
||||
},
|
||||
dontPush: true
|
||||
dontPush: true,
|
||||
bounds: box,
|
||||
title: 'New Tabs'
|
||||
};
|
||||
|
||||
new Group([], $.extend({}, group, options));
|
||||
new Group([], options);
|
||||
}
|
||||
}
|
||||
|
||||
var group = this.getNewTabGroup();
|
||||
if(!group) {
|
||||
var box = this.getBoundsForNewTabGroup();
|
||||
var options = {
|
||||
locked: {
|
||||
close: true,
|
||||
title: true
|
||||
},
|
||||
dontPush: true,
|
||||
bounds: box,
|
||||
title: 'New Tabs'
|
||||
};
|
||||
|
||||
new Group([], options);
|
||||
}
|
||||
this._inited = true;
|
||||
this.save(); // for nextID
|
||||
}catch(e){
|
||||
Utils.log("error in recons: "+e);
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
storageSanity: function(data) {
|
||||
groupStorageSanity: function(groupData) {
|
||||
// TODO: check everything
|
||||
if(!data.groups)
|
||||
return false;
|
||||
|
||||
var sane = true;
|
||||
$.each(data.groups, function(index, group) {
|
||||
if(!isRect(group.bounds)) {
|
||||
Utils.log('Groups.storageSanity: bad bounds', group.bounds);
|
||||
sane = false;
|
||||
}
|
||||
});
|
||||
if(!isRect(groupData.bounds)) {
|
||||
Utils.log('Groups.groupStorageSanity: bad bounds', groupData.bounds);
|
||||
sane = false;
|
||||
}
|
||||
|
||||
return sane;
|
||||
},
|
||||
|
@ -11,6 +11,7 @@
|
||||
// close - function()
|
||||
// addOnClose - function(referenceObject, callback)
|
||||
// removeOnClose - function(referenceObject)
|
||||
// save - function()
|
||||
//
|
||||
// ... and this property:
|
||||
// defaultSize - a Point
|
||||
@ -73,6 +74,7 @@ window.Item.prototype = {
|
||||
Utils.assert('Subclass must provide close', typeof(this.close) == 'function');
|
||||
Utils.assert('Subclass must provide addOnClose', typeof(this.addOnClose) == 'function');
|
||||
Utils.assert('Subclass must provide removeOnClose', typeof(this.removeOnClose) == 'function');
|
||||
Utils.assert('Subclass must provide save', typeof(this.save) == 'function');
|
||||
Utils.assert('Subclass must provide defaultSize', isPoint(this.defaultSize));
|
||||
Utils.assert('Subclass must provide locked', this.locked);
|
||||
|
||||
@ -136,6 +138,7 @@ window.Item.prototype = {
|
||||
setUserSize: function() {
|
||||
Utils.assert('this.bounds', isRect(this.bounds));
|
||||
this.userSize = new Point(this.bounds.width, this.bounds.height);
|
||||
this.save();
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -153,6 +156,14 @@ window.Item.prototype = {
|
||||
$(this.container).css({"-moz-transform": value});
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: setParent
|
||||
//
|
||||
setParent: function(parent) {
|
||||
this.parent = parent;
|
||||
this.save();
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: pushAway
|
||||
// Pushes all other items away so none overlap this Item.
|
||||
|
@ -5,6 +5,7 @@ Storage = {
|
||||
GROUP_DATA_IDENTIFIER: "tabcandy-group",
|
||||
GROUPS_DATA_IDENTIFIER: "tabcandy-groups",
|
||||
TAB_DATA_IDENTIFIER: "tabcandy-tab",
|
||||
UI_DATA_IDENTIFIER: "tabcandy-ui",
|
||||
|
||||
// ----------
|
||||
init: function() {
|
||||
@ -12,9 +13,31 @@ Storage = {
|
||||
.getService(Components.interfaces.nsISessionStore);
|
||||
},
|
||||
|
||||
// ----------
|
||||
wipe: function() {
|
||||
try {
|
||||
var win = Utils.getCurrentWindow();
|
||||
var self = this;
|
||||
|
||||
// ___ Tabs
|
||||
Tabs.forEach(function(tab) {
|
||||
self.saveTab(tab.raw, null);
|
||||
});
|
||||
|
||||
// ___ Other
|
||||
this.saveGroupsData(win, {});
|
||||
this.saveUIData(win, {});
|
||||
|
||||
this._sessionStore.setWindowValue(win, this.GROUP_DATA_IDENTIFIER,
|
||||
JSON.stringify({}));
|
||||
} catch (e) {
|
||||
Utils.log("Error in wipe: "+e);
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
saveTab: function(tab, data) {
|
||||
/* Utils.log("AAAAAAAAAAAAAAAAAAAAAAAAAAA saving tab data, tab: " + tab.toSource() + ", data: "+data.toSource()); */
|
||||
/* Utils.log("AAAAAAAAAAAAAAAAAAAAAAAAAAA saving tab data"); */
|
||||
this._sessionStore.setTabValue(tab, this.TAB_DATA_IDENTIFIER,
|
||||
JSON.stringify(data));
|
||||
},
|
||||
@ -32,6 +55,8 @@ Storage = {
|
||||
// getWindowValue will fail if the property doesn't exist
|
||||
Utils.log("Error in readTabData: "+e);
|
||||
}
|
||||
|
||||
/* Utils.log('tab', existingData); */
|
||||
return existingData;
|
||||
},
|
||||
|
||||
@ -69,71 +94,48 @@ Storage = {
|
||||
|
||||
// ----------
|
||||
saveGroupsData: function(win, data) {
|
||||
/* Utils.log("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG " + data.toSource()); */
|
||||
this._sessionStore.setWindowValue(win, this.GROUPS_DATA_IDENTIFIER,
|
||||
JSON.stringify(data));
|
||||
this.saveData(win, this.GROUPS_DATA_IDENTIFIER, data);
|
||||
},
|
||||
|
||||
// ----------
|
||||
readGroupsData: function(win) {
|
||||
return this.readData(win, this.GROUPS_DATA_IDENTIFIER);
|
||||
},
|
||||
|
||||
// ----------
|
||||
saveUIData: function(win, data) {
|
||||
this.saveData(win, this.UI_DATA_IDENTIFIER, data);
|
||||
},
|
||||
|
||||
// ----------
|
||||
readUIData: function(win) {
|
||||
return this.readData(win, this.UI_DATA_IDENTIFIER);
|
||||
},
|
||||
|
||||
// ----------
|
||||
saveData: function(win, id, data) {
|
||||
try {
|
||||
this._sessionStore.setWindowValue(win, id, JSON.stringify(data));
|
||||
} catch (e) {
|
||||
Utils.log("Error in saveData: "+e);
|
||||
}
|
||||
|
||||
/* Utils.log('save data', id, data); */
|
||||
},
|
||||
|
||||
// ----------
|
||||
readData: function(win, id) {
|
||||
var existingData = {};
|
||||
try {
|
||||
/* Utils.log("readGroupsData: "+this._sessionStore.getWindowValue(win, this.GROUPS_DATA_IDENTIFIER)); */
|
||||
existingData = JSON.parse(
|
||||
this._sessionStore.getWindowValue(win, this.GROUPS_DATA_IDENTIFIER)
|
||||
);
|
||||
var data = this._sessionStore.getWindowValue(win, id);
|
||||
if(data)
|
||||
existingData = JSON.parse(data);
|
||||
} catch (e) {
|
||||
// getWindowValue will fail if the property doesn't exist
|
||||
Utils.log("Error in readData: "+e);
|
||||
}
|
||||
|
||||
/* Utils.log('read data', id, existingData); */
|
||||
return existingData;
|
||||
},
|
||||
|
||||
// ----------
|
||||
read: function() {
|
||||
var data = {};
|
||||
var file = this.getFile();
|
||||
if(file.exists()) {
|
||||
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIConverterInputStream);
|
||||
fstream.init(file, -1, 0, 0);
|
||||
cstream.init(fstream, "UTF-8", 0, 0); // you can use another encoding here if you wish
|
||||
|
||||
let (str = {}) {
|
||||
cstream.readString(-1, str); // read the whole file and put it in str.value
|
||||
if(str.value)
|
||||
data = JSON.parse(str.value);
|
||||
}
|
||||
cstream.close(); // this closes fstream
|
||||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
// ----------
|
||||
write: function(data) {
|
||||
var file = this.getFile();
|
||||
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
|
||||
var str = JSON.stringify(data);
|
||||
foStream.write(str, str.length);
|
||||
foStream.close();
|
||||
},
|
||||
|
||||
// ----------
|
||||
getFile: function() {
|
||||
var file = Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("ProfD", Components.interfaces.nsIFile);
|
||||
|
||||
file.append('tabcandy');
|
||||
if(!file.exists())
|
||||
file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
|
||||
|
||||
file.append(Switch.name + '.json');
|
||||
return file;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,7 @@ window.TabItem = function(container, tab) {
|
||||
|
||||
this._init(container);
|
||||
|
||||
this.reconnected = false;
|
||||
this._hasBeenDrawn = false;
|
||||
this.tab = tab;
|
||||
this.setResizable(true);
|
||||
@ -22,6 +23,13 @@ window.TabItem = function(container, tab) {
|
||||
this.tab.mirror.addOnClose(this, function(who, info) {
|
||||
TabItems.unregister(self);
|
||||
});
|
||||
|
||||
this.tab.mirror.addSubscriber(this, 'urlChanged', function(who, info) {
|
||||
if(!self.reconnected && (info.oldURL == 'about:blank' || !info.oldURL))
|
||||
TabItems.reconnect(self);
|
||||
|
||||
self.save();
|
||||
});
|
||||
};
|
||||
|
||||
window.TabItem.prototype = $.extend(new Item(), {
|
||||
@ -37,13 +45,13 @@ window.TabItem.prototype = $.extend(new Item(), {
|
||||
|
||||
// ----------
|
||||
save: function() {
|
||||
/* Utils.log((this.tab ? this.tab.url : ''), this.reconnected); */
|
||||
try{
|
||||
if (!("tab" in this) || !("raw" in this.tab) || !this.reconnected) // too soon to save
|
||||
return;
|
||||
|
||||
var data = this.getStorageData();
|
||||
/* Utils.log("data to save", data); */
|
||||
Storage.saveTab(this.tab.raw, data);
|
||||
if(TabItems.storageSanity(data))
|
||||
Storage.saveTab(this.tab.raw, data);
|
||||
}catch(e){
|
||||
Utils.log("Error in saving tab value: "+e);
|
||||
}
|
||||
@ -320,20 +328,19 @@ window.TabItems = {
|
||||
|
||||
if(TabItems.reconnect(item))
|
||||
reconnected = true;
|
||||
else if(!tab.url || tab.url == 'about:blank') {
|
||||
tab.mirror.addSubscriber(item, 'urlChanged', function(who, info) {
|
||||
Utils.assert('changing away from blank', info.oldURL == 'about:blank' || !info.oldURL);
|
||||
TabItems.reconnect(item);
|
||||
who.removeSubscriber(item);
|
||||
});
|
||||
}
|
||||
else
|
||||
Groups.newTab(item);
|
||||
}
|
||||
});
|
||||
/* Utils.log("reconnected: "+reconnected); */
|
||||
|
||||
/*
|
||||
Utils.log(reconnected, $div.length, !!Groups);
|
||||
if(!reconnected && $div.length == 1 && Groups){
|
||||
Utils.log('new tab');
|
||||
Groups.newTab($div.data('tabItem'));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// TODO: Figure out this really weird bug?
|
||||
@ -448,6 +455,14 @@ window.TabItems = {
|
||||
return $(tab).data("tabItem");
|
||||
},
|
||||
|
||||
// ----------
|
||||
saveAll: function() {
|
||||
var items = this.getItems();
|
||||
$.each(items, function(index, item) {
|
||||
item.save();
|
||||
});
|
||||
},
|
||||
|
||||
// ----------
|
||||
reconstitute: function() {
|
||||
var items = this.getItems();
|
||||
@ -461,34 +476,26 @@ window.TabItems = {
|
||||
// ----------
|
||||
storageSanity: function(data) {
|
||||
// TODO: check everything
|
||||
if(!data.tabs)
|
||||
return false;
|
||||
|
||||
var sane = true;
|
||||
$.each(data.tabs, function(index, tab) {
|
||||
if(!isRect(tab.bounds)) {
|
||||
Utils.log('TabItems.storageSanity: bad bounds', tab.bounds);
|
||||
sane = false;
|
||||
}
|
||||
});
|
||||
if(!isRect(data.bounds)) {
|
||||
Utils.log('TabItems.storageSanity: bad bounds', data.bounds);
|
||||
sane = false;
|
||||
}
|
||||
|
||||
return sane;
|
||||
},
|
||||
|
||||
// ----------
|
||||
reconnect: function(item) {
|
||||
var found = false;
|
||||
|
||||
try{
|
||||
/* Utils.log("trying to reconnect"); */
|
||||
if(item.reconnected) {
|
||||
/* Utils.log("already done"); */
|
||||
return true;
|
||||
}
|
||||
|
||||
var found = false;
|
||||
|
||||
var tab = Storage.getTabData(item.tab.raw);
|
||||
/* Utils.log("this is our tab", tab, item.tab.url); */
|
||||
if (tab) {
|
||||
if (tab && this.storageSanity(tab)) {
|
||||
if(item.parent)
|
||||
item.parent.remove(item);
|
||||
|
||||
@ -499,11 +506,12 @@ window.TabItems = {
|
||||
|
||||
if(tab.groupID) {
|
||||
var group = Groups.group(tab.groupID);
|
||||
/* Utils.log("group found: " + group); */
|
||||
group.add(item);
|
||||
if(group) {
|
||||
group.add(item);
|
||||
|
||||
if(item.tab == Utils.activeTab)
|
||||
Groups.setActiveGroup(item.parent);
|
||||
if(item.tab == Utils.activeTab)
|
||||
Groups.setActiveGroup(item.parent);
|
||||
}
|
||||
}
|
||||
|
||||
Groups.updateTabBarForActiveGroup();
|
||||
|
@ -8,7 +8,7 @@ window.Keys = {meta: false};
|
||||
Navbar = {
|
||||
// ----------
|
||||
get el(){
|
||||
var win = Utils.activeWindow;
|
||||
var win = Utils.getCurrentWindow();
|
||||
if(win) {
|
||||
var navbar = win.gBrowser.ownerDocument.getElementById("navigator-toolbox");
|
||||
return navbar;
|
||||
@ -18,7 +18,7 @@ Navbar = {
|
||||
},
|
||||
|
||||
get urlBar(){
|
||||
var win = Utils.activeWindow;
|
||||
var win = Utils.getCurrentWindow();
|
||||
if(win) {
|
||||
var navbar = win.gBrowser.ownerDocument.getElementById("urlbar");
|
||||
return navbar;
|
||||
@ -535,7 +535,7 @@ UIClass.prototype = {
|
||||
var me = this;
|
||||
setTimeout(function() { // Marshal event from chrome thread to DOM thread
|
||||
try{
|
||||
if(me.contentWindow.location.host == "tabcandy") {
|
||||
if(me.contentWindow == window) {
|
||||
self.focused = true;
|
||||
Page.hideChrome();
|
||||
} else {
|
||||
@ -554,47 +554,30 @@ UIClass.prototype = {
|
||||
}, 1);
|
||||
});
|
||||
|
||||
// ___ Page
|
||||
Page.init();
|
||||
|
||||
// ___ Storage
|
||||
var data = Storage.read();
|
||||
var sane = this.storageSanity(data);
|
||||
if(!sane || data.dataVersion < 2) {
|
||||
data.groups = null;
|
||||
data.tabs = null;
|
||||
data.pageBounds = null;
|
||||
|
||||
if(!sane)
|
||||
alert('storage data is bad; starting fresh');
|
||||
}
|
||||
|
||||
var groupsData = Storage.readGroupsData(Utils.activeWindow);
|
||||
var groupData = Storage.readGroupData(Utils.activeWindow);
|
||||
|
||||
/*
|
||||
Utils.log("in UI init");
|
||||
Utils.log(data.toSource());
|
||||
Utils.log(groupsData.toSource());
|
||||
Utils.log(groupData.toSource());
|
||||
*/
|
||||
Groups.reconstitute(groupsData, groupData);
|
||||
TabItems.init();
|
||||
TabItems.reconstitute();
|
||||
|
||||
$(window).bind('beforeunload', function() {
|
||||
if(self.initialized)
|
||||
self.save();
|
||||
|
||||
self.showChrome();
|
||||
self.tabBar.showAllTabs();
|
||||
});
|
||||
|
||||
// ___ Page
|
||||
Page.init();
|
||||
|
||||
// ___ Storage
|
||||
var currentWindow = Utils.getCurrentWindow();
|
||||
var data = Storage.readUIData(currentWindow);
|
||||
this.storageSanity(data);
|
||||
|
||||
var groupsData = Storage.readGroupsData(currentWindow);
|
||||
var groupData = Storage.readGroupData(currentWindow);
|
||||
Groups.reconstitute(groupsData, groupData);
|
||||
|
||||
TabItems.init();
|
||||
TabItems.reconstitute();
|
||||
|
||||
// ___ resizing
|
||||
data.pageBounds = null;
|
||||
if(data.pageBounds) {
|
||||
this.pageBounds = data.pageBounds;
|
||||
this.resize();
|
||||
this.resize(true);
|
||||
} else
|
||||
this.pageBounds = Items.getPageBounds();
|
||||
|
||||
@ -607,6 +590,7 @@ UIClass.prototype = {
|
||||
|
||||
// ___ Done
|
||||
this.initialized = true;
|
||||
this.save(); // for this.pageBounds
|
||||
}catch(e) {
|
||||
Utils.log("Error in UIClass(): " + e);
|
||||
Utils.log(e.fileName);
|
||||
@ -692,6 +676,7 @@ UIClass.prototype = {
|
||||
});
|
||||
|
||||
this.pageBounds = Items.getPageBounds();
|
||||
this.save();
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -716,10 +701,21 @@ UIClass.prototype = {
|
||||
code: function() {
|
||||
location.href = '../../index.html';
|
||||
}
|
||||
}, {
|
||||
name: 'code docs',
|
||||
code: function() {
|
||||
location.href = '../../doc/index.html';
|
||||
}
|
||||
}, {
|
||||
name: 'save',
|
||||
code: function() {
|
||||
self.save();
|
||||
self.saveAll();
|
||||
}
|
||||
}, {
|
||||
name: 'reset',
|
||||
code: function() {
|
||||
Storage.wipe();
|
||||
location.href = '';
|
||||
}
|
||||
}];
|
||||
|
||||
@ -736,21 +732,24 @@ UIClass.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
saveAll: function() {
|
||||
this.save();
|
||||
Groups.saveAll();
|
||||
TabItems.saveAll();
|
||||
},
|
||||
|
||||
// ----------
|
||||
save: function() {
|
||||
return;
|
||||
if(!this.initialized)
|
||||
return;
|
||||
|
||||
var data = {
|
||||
dataVersion: 2,
|
||||
groups: Groups.getStorageData(),
|
||||
tabs: TabItems.getStorageData(),
|
||||
pageBounds: Items.getPageBounds()
|
||||
pageBounds: this.pageBounds
|
||||
};
|
||||
|
||||
/* Utils.error(this.pageBounds, data.pageBounds); */
|
||||
if(this.storageSanity(data))
|
||||
Storage.write(data);
|
||||
else
|
||||
alert('storage data is bad; reverting to previous version');
|
||||
Storage.saveUIData(Utils.getCurrentWindow(), data);
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -758,17 +757,13 @@ UIClass.prototype = {
|
||||
if($.isEmptyObject(data))
|
||||
return true;
|
||||
|
||||
var sane = true;
|
||||
sane = sane && typeof(data.dataVersion) == 'number';
|
||||
sane = sane && isRect(data.pageBounds);
|
||||
if(!isRect(data.pageBounds)) {
|
||||
Utils.log('UI.storageSanity: bad pageBounds', data.pageBounds);
|
||||
data.pageBounds = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(data.tabs)
|
||||
sane = sane && TabItems.storageSanity(data.tabs);
|
||||
|
||||
if(data.groups)
|
||||
sane = sane && Groups.storageSanity(data.groups);
|
||||
|
||||
return sane;
|
||||
return true;
|
||||
},
|
||||
|
||||
// ----------
|
||||
|
@ -1,13 +1,14 @@
|
||||
// Title: tabs.js
|
||||
(function(){
|
||||
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
|
||||
// ##########
|
||||
// Class: XULApp
|
||||
// Singelton
|
||||
var XULApp = {
|
||||
appWindowType: "navigator:browser",
|
||||
tabStripForWindow: function(aWindow) {
|
||||
@ -30,7 +31,8 @@ var XULApp = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ##########
|
||||
// Class: Dictionary
|
||||
function Dictionary() {
|
||||
var keys = [];
|
||||
var values = [];
|
||||
@ -69,6 +71,8 @@ function Dictionary() {
|
||||
this.__defineGetter__("length", function() { return keys.length; });
|
||||
}
|
||||
|
||||
// ##########
|
||||
// Class: ImmutableArray
|
||||
function ImmutableArray(baseArray) {
|
||||
var self = this;
|
||||
var UNSUPPORTED_MUTATOR_METHODS = ["pop", "push", "reverse", "shift",
|
||||
@ -86,117 +90,9 @@ function ImmutableArray(baseArray) {
|
||||
self.__proto__ = baseArray;
|
||||
}
|
||||
|
||||
function WindowWatcher() {
|
||||
var self = this;
|
||||
|
||||
var observer = {
|
||||
observe: function(window, event) {
|
||||
if (event == "domwindowopened") {
|
||||
if (self.onWindowOpened)
|
||||
self.onWindowOpened(window);
|
||||
} else
|
||||
if (self.onWindowClosed)
|
||||
self.onWindowClosed(window);
|
||||
}
|
||||
};
|
||||
|
||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Ci.nsIWindowWatcher);
|
||||
ww.registerNotification(observer);
|
||||
|
||||
Extension.addUnloadMethod(
|
||||
this,
|
||||
function() {
|
||||
ww.unregisterNotification(observer);
|
||||
});
|
||||
}
|
||||
|
||||
// When this object is instantiated, the given onLoad() is called for
|
||||
// all browser windows, and subsequently for all newly-opened browser
|
||||
// windows. When a browser window closes, onUnload() is called.
|
||||
// onUnload() is also called once for each browser window when the
|
||||
// extension is unloaded.
|
||||
|
||||
function BrowserWatcher(options) {
|
||||
var pendingHandlers = [];
|
||||
|
||||
function makeSafeFunc(func) {
|
||||
function safeFunc(window) {
|
||||
try {
|
||||
func(window);
|
||||
} catch (e) {
|
||||
Utils.log(e);
|
||||
}
|
||||
};
|
||||
return safeFunc;
|
||||
}
|
||||
|
||||
function addUnloader(chromeWindow, func) {
|
||||
function onUnload() {
|
||||
chromeWindow.removeEventListener("unload", onUnload, false);
|
||||
pendingHandlers.splice(pendingHandlers.indexOf(onUnload), 1);
|
||||
func(chromeWindow);
|
||||
}
|
||||
pendingHandlers.push(onUnload);
|
||||
chromeWindow.addEventListener("unload", onUnload, false);
|
||||
}
|
||||
|
||||
function loadAndBind(chromeWindow) {
|
||||
if (options.onLoad)
|
||||
(makeSafeFunc(options.onLoad))(chromeWindow);
|
||||
if (options.onUnload)
|
||||
addUnloader(chromeWindow, makeSafeFunc(options.onUnload));
|
||||
}
|
||||
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Ci.nsIWindowMediator);
|
||||
|
||||
var enumerator = wm.getEnumerator(XULApp.appWindowType);
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var chromeWindow = enumerator.getNext();
|
||||
if (chromeWindow.gIsDoneLoading)
|
||||
loadAndBind(chromeWindow);
|
||||
else
|
||||
onWindowOpened(chromeWindow);
|
||||
}
|
||||
|
||||
function onWindowOpened(chromeWindow) {
|
||||
function removeListener() {
|
||||
chromeWindow.removeEventListener("load", onLoad, false);
|
||||
pendingHandlers.splice(pendingHandlers.indexOf(removeListener), 1);
|
||||
}
|
||||
function onLoad() {
|
||||
removeListener();
|
||||
var type = chromeWindow.document.documentElement
|
||||
.getAttribute("windowtype");
|
||||
if (type == XULApp.appWindowType)
|
||||
loadAndBind(chromeWindow);
|
||||
}
|
||||
chromeWindow.addEventListener("load", onLoad, false);
|
||||
pendingHandlers.push(removeListener);
|
||||
}
|
||||
|
||||
var ww = new WindowWatcher();
|
||||
ww.onWindowOpened = onWindowOpened;
|
||||
|
||||
Extension.addUnloadMethod(
|
||||
this,
|
||||
function() {
|
||||
ww.unload();
|
||||
var handlers = pendingHandlers.slice();
|
||||
handlers.forEach(function(handler) { handler(); });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ##########
|
||||
// Class: Extension
|
||||
// Singleton
|
||||
var Extension = {
|
||||
// === {{{Extension.addUnloadMethod()}}} ===
|
||||
//
|
||||
@ -220,14 +116,8 @@ var Extension = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ##########
|
||||
// Class: EventListenerMixIns
|
||||
function EventListenerMixIns(mixInto) {
|
||||
var mixIns = {};
|
||||
|
||||
@ -256,6 +146,8 @@ function EventListenerMixIns(mixInto) {
|
||||
});
|
||||
}
|
||||
|
||||
// ##########
|
||||
// Class: EventListenerMixIn
|
||||
function EventListenerMixIn(options) {
|
||||
var listeners = [];
|
||||
|
||||
@ -578,29 +470,12 @@ window.TabsManager = $.extend(new Subscribable(), {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
var browserWatcher = new BrowserWatcher(
|
||||
{onLoad: function(chromeWindow) {
|
||||
var trackedWindow = trackedWindows.get(chromeWindow);
|
||||
if (!trackedWindow)
|
||||
trackedWindows.set(chromeWindow,
|
||||
new BrowserWindow(chromeWindow));
|
||||
},
|
||||
onUnload: function(chromeWindow) {
|
||||
var browserWindow = trackedWindows.get(chromeWindow);
|
||||
trackedWindows.remove(chromeWindow);
|
||||
browserWindow.unload();
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
this.__defineGetter__("tabs", function() { return tabs; });
|
||||
|
||||
Extension.addUnloadMethod(
|
||||
this,
|
||||
function() {
|
||||
tabsMixIns.unload();
|
||||
/* browserWatcher.unload(); */
|
||||
});
|
||||
|
||||
window.Tabs = tabs;
|
||||
|
@ -23,7 +23,7 @@
|
||||
<script type="text/javascript;version=1.8" src="js/storage.js"></script>
|
||||
<script type="text/javascript;version=1.8" src="../../js/core/toolbar-button.js"></script>
|
||||
<script type="text/javascript;version=1.8">
|
||||
Utils.log('it begins!');
|
||||
Utils.log('it begins! --------------------');
|
||||
/* Utils.testLogging(); */
|
||||
</script>
|
||||
<script type="text/javascript;version=1.8" src="../../js/core/tabs.js"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user