mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
+ fixed: if you quit firefox with tab candy present, and more than one window open, when you restart, everything will be broken
+ massaged the whole start up sequence
This commit is contained in:
parent
2d7ca7cd82
commit
a8c8eef11b
@ -286,9 +286,10 @@ window.TabItems = {
|
|||||||
var reconnected = false;
|
var reconnected = false;
|
||||||
$div.each(function() {
|
$div.each(function() {
|
||||||
var tab = Tabs.tab(this);
|
var tab = Tabs.tab(this);
|
||||||
if(tab == Utils.homeTab)
|
if(tab == Utils.homeTab) {
|
||||||
$(this).hide();
|
$(this).hide();
|
||||||
else {
|
reconnected = true;
|
||||||
|
} else {
|
||||||
var item = new TabItem(this, tab);
|
var item = new TabItem(this, tab);
|
||||||
$(this).data('tabItem', item);
|
$(this).data('tabItem', item);
|
||||||
|
|
||||||
|
@ -64,10 +64,14 @@ var Tabbar = {
|
|||||||
_hidden: false,
|
_hidden: false,
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
get el(){ return window.Tabs[0].raw.parentNode; },
|
get el() {
|
||||||
|
return window.Tabs[0].raw.parentNode;
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
height: window.Tabs[0].raw.parentNode.getBoundingClientRect().height,
|
get height() {
|
||||||
|
return window.Tabs[0].raw.parentNode.getBoundingClientRect().height;
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
hide: function(animate) {
|
hide: function(animate) {
|
||||||
@ -448,121 +452,133 @@ ArrangeClass.prototype = {
|
|||||||
// Class: UIClass
|
// Class: UIClass
|
||||||
// Singleton top-level UI manager. TODO: Integrate with <Page>.
|
// Singleton top-level UI manager. TODO: Integrate with <Page>.
|
||||||
function UIClass(){
|
function UIClass(){
|
||||||
// Variable: navBar
|
if(window.Tabs)
|
||||||
// A reference to the <Navbar>, for manipulating the browser's nav bar.
|
this.init();
|
||||||
this.navBar = Navbar;
|
else {
|
||||||
|
var self = this;
|
||||||
// Variable: tabBar
|
TabsManager.addSubscriber(this, 'load', function() {
|
||||||
// A reference to the <Tabbar>, for manipulating the browser's tab bar.
|
self.init();
|
||||||
this.tabBar = Tabbar;
|
});
|
||||||
|
|
||||||
// Variable: devMode
|
|
||||||
// If true (set by an url parameter), adds extra features to the screen.
|
|
||||||
// TODO: Integrate with the dev menu
|
|
||||||
this.devMode = false;
|
|
||||||
|
|
||||||
// Variable: currentTab
|
|
||||||
// Keeps track of which <Tabs> tab we are currently on.
|
|
||||||
// Used to facilitate zooming down from a previous tab.
|
|
||||||
this.currentTab = Utils.activeTab;
|
|
||||||
|
|
||||||
// Variable: focused
|
|
||||||
// Keeps track of whether Tab Candy is focused.
|
|
||||||
this.focused = (Utils.activeTab == Utils.homeTab);
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// ___ URL Params
|
|
||||||
var params = document.location.search.replace('?', '').split('&');
|
|
||||||
$.each(params, function(index, param) {
|
|
||||||
var parts = param.split('=');
|
|
||||||
if(parts[0] == 'dev' && parts[1] == '1')
|
|
||||||
self.devMode = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// ___ Dev Mode
|
|
||||||
if(this.devMode) {
|
|
||||||
Switch.insert('body', '');
|
|
||||||
$('<br><br>').appendTo("#actions");
|
|
||||||
this._addArrangements();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ___ Navbar
|
|
||||||
if(this.focused) {
|
|
||||||
this.tabBar.hide();
|
|
||||||
this.navBar.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
Tabs.onFocus(function() {
|
|
||||||
setTimeout(function() { // Marshal event from chrome thread to DOM thread
|
|
||||||
try{
|
|
||||||
if(this.contentWindow.location.host == "tabcandy") {
|
|
||||||
self.focused = true;
|
|
||||||
self.navBar.hide();
|
|
||||||
self.tabBar.hide();
|
|
||||||
} else {
|
|
||||||
self.focused = false;
|
|
||||||
self.navBar.show();
|
|
||||||
}
|
|
||||||
}catch(e){
|
|
||||||
Utils.log()
|
|
||||||
}
|
|
||||||
}, 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
Tabs.onOpen(function(a, b) {
|
|
||||||
setTimeout(function() { // Marshal event from chrome thread to DOM thread
|
|
||||||
self.navBar.show();
|
|
||||||
}, 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');
|
|
||||||
}
|
|
||||||
|
|
||||||
Groups.reconstitute(data.groups);
|
|
||||||
TabItems.reconstitute(data.tabs);
|
|
||||||
|
|
||||||
$(window).bind('beforeunload', function() {
|
|
||||||
if(self.initialized)
|
|
||||||
self.save();
|
|
||||||
|
|
||||||
self.navBar.show();
|
|
||||||
self.tabBar.show(false);
|
|
||||||
self.tabBar.showAllTabs();
|
|
||||||
});
|
|
||||||
|
|
||||||
// ___ resizing
|
|
||||||
if(data.pageBounds) {
|
|
||||||
this.pageBounds = data.pageBounds;
|
|
||||||
this.resize();
|
|
||||||
} else
|
|
||||||
this.pageBounds = Items.getPageBounds();
|
|
||||||
|
|
||||||
$(window).resize(function() {
|
|
||||||
self.resize();
|
|
||||||
});
|
|
||||||
|
|
||||||
// ___ Dev Menu
|
|
||||||
this.addDevMenu();
|
|
||||||
|
|
||||||
// ___ Done
|
|
||||||
this.initialized = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
UIClass.prototype = {
|
UIClass.prototype = {
|
||||||
|
// ----------
|
||||||
|
init: function() {
|
||||||
|
// Variable: navBar
|
||||||
|
// A reference to the <Navbar>, for manipulating the browser's nav bar.
|
||||||
|
this.navBar = Navbar;
|
||||||
|
|
||||||
|
// Variable: tabBar
|
||||||
|
// A reference to the <Tabbar>, for manipulating the browser's tab bar.
|
||||||
|
this.tabBar = Tabbar;
|
||||||
|
|
||||||
|
// Variable: devMode
|
||||||
|
// If true (set by an url parameter), adds extra features to the screen.
|
||||||
|
// TODO: Integrate with the dev menu
|
||||||
|
this.devMode = false;
|
||||||
|
|
||||||
|
// Variable: currentTab
|
||||||
|
// Keeps track of which <Tabs> tab we are currently on.
|
||||||
|
// Used to facilitate zooming down from a previous tab.
|
||||||
|
this.currentTab = Utils.activeTab;
|
||||||
|
|
||||||
|
// Variable: focused
|
||||||
|
// Keeps track of whether Tab Candy is focused.
|
||||||
|
this.focused = (Utils.activeTab == Utils.homeTab);
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// ___ URL Params
|
||||||
|
var params = document.location.search.replace('?', '').split('&');
|
||||||
|
$.each(params, function(index, param) {
|
||||||
|
var parts = param.split('=');
|
||||||
|
if(parts[0] == 'dev' && parts[1] == '1')
|
||||||
|
self.devMode = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ___ Dev Mode
|
||||||
|
if(this.devMode) {
|
||||||
|
Switch.insert('body', '');
|
||||||
|
$('<br><br>').appendTo("#actions");
|
||||||
|
this._addArrangements();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ___ Navbar
|
||||||
|
if(this.focused) {
|
||||||
|
this.tabBar.hide();
|
||||||
|
this.navBar.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
Tabs.onFocus(function() {
|
||||||
|
setTimeout(function() { // Marshal event from chrome thread to DOM thread
|
||||||
|
try{
|
||||||
|
if(this.contentWindow.location.host == "tabcandy") {
|
||||||
|
self.focused = true;
|
||||||
|
self.navBar.hide();
|
||||||
|
self.tabBar.hide();
|
||||||
|
} else {
|
||||||
|
self.focused = false;
|
||||||
|
self.navBar.show();
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
Utils.log()
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
Tabs.onOpen(function(a, b) {
|
||||||
|
setTimeout(function() { // Marshal event from chrome thread to DOM thread
|
||||||
|
self.navBar.show();
|
||||||
|
}, 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');
|
||||||
|
}
|
||||||
|
|
||||||
|
Groups.reconstitute(data.groups);
|
||||||
|
TabItems.reconstitute(data.tabs);
|
||||||
|
|
||||||
|
$(window).bind('beforeunload', function() {
|
||||||
|
if(self.initialized)
|
||||||
|
self.save();
|
||||||
|
|
||||||
|
self.navBar.show();
|
||||||
|
self.tabBar.show(false);
|
||||||
|
self.tabBar.showAllTabs();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ___ resizing
|
||||||
|
if(data.pageBounds) {
|
||||||
|
this.pageBounds = data.pageBounds;
|
||||||
|
this.resize();
|
||||||
|
} else
|
||||||
|
this.pageBounds = Items.getPageBounds();
|
||||||
|
|
||||||
|
$(window).resize(function() {
|
||||||
|
self.resize();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ___ Dev Menu
|
||||||
|
this.addDevMenu();
|
||||||
|
|
||||||
|
// ___ Done
|
||||||
|
this.initialized = true;
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
resize: function() {
|
resize: function() {
|
||||||
/* Groups.repositionNewTabGroup(); */
|
/* Groups.repositionNewTabGroup(); */
|
||||||
|
@ -180,7 +180,17 @@ Mirror.prototype = $.extend(new Subscribable(), {
|
|||||||
// ##########
|
// ##########
|
||||||
// Class: TabMirror
|
// Class: TabMirror
|
||||||
// A singleton that manages all of the <Mirror>s in the system.
|
// A singleton that manages all of the <Mirror>s in the system.
|
||||||
var TabMirror = function( ){ this.init() }
|
var TabMirror = function() {
|
||||||
|
if(window.Tabs)
|
||||||
|
this.init();
|
||||||
|
else {
|
||||||
|
var self = this;
|
||||||
|
TabsManager.addSubscriber(this, 'load', function() {
|
||||||
|
self.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TabMirror.prototype = {
|
TabMirror.prototype = {
|
||||||
// ----------
|
// ----------
|
||||||
// Function: init
|
// Function: init
|
||||||
|
@ -319,279 +319,303 @@ function EventListenerMixIn(options) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Class: Tabs
|
// ##########
|
||||||
|
// Class: TabsManager
|
||||||
// Singelton for dealing with the actual tabs in the browser.
|
// Singelton for dealing with the actual tabs in the browser.
|
||||||
function Tabs() {
|
window.TabsManager = $.extend(new Subscribable(), {
|
||||||
var trackedWindows = new Dictionary();
|
// ----------
|
||||||
var trackedTabs = new Dictionary();
|
// Function: init
|
||||||
|
// Sets up the TabsManager and window.Tabs
|
||||||
|
init: function() {
|
||||||
|
var self = this;
|
||||||
|
/*
|
||||||
|
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||||
|
.getService(Ci.nsIWindowMediator);
|
||||||
|
var chromeWindow = wm.getMostRecentWindow("navigator:browser");
|
||||||
|
*/
|
||||||
|
var chromeWindow = Utils.activeWindow;
|
||||||
|
if(!chromeWindow.getBrowser || !chromeWindow.getBrowser())
|
||||||
|
chromeWindow = null;
|
||||||
|
|
||||||
var windows = {
|
if(!chromeWindow) {
|
||||||
get focused() {
|
setTimeout(function() {
|
||||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
self.init();
|
||||||
.getService(Ci.nsIWindowMediator);
|
}, 100);
|
||||||
var chromeWindow = wm.getMostRecentWindow("navigator:browser");
|
|
||||||
/* Utils.log( trackedWindows ) */
|
return;
|
||||||
if (chromeWindow)
|
|
||||||
return trackedWindows.get(chromeWindow);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: AZA ADDED THIS TO MAKE IT WORK WHEN JETPACK NOT INSTALLED
|
var trackedWindows = new Dictionary();
|
||||||
// TOTALLY HACKY :(
|
var trackedTabs = new Dictionary();
|
||||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
|
||||||
.getService(Ci.nsIWindowMediator);
|
|
||||||
var chromeWindow = wm.getMostRecentWindow("navigator:browser");
|
|
||||||
trackedWindows.set(chromeWindow,
|
|
||||||
new BrowserWindow(chromeWindow));
|
|
||||||
|
|
||||||
windows.__proto__ = trackedWindows.values;
|
trackedWindows.set(chromeWindow,
|
||||||
|
new BrowserWindow(chromeWindow));
|
||||||
|
|
||||||
var tabs = {
|
var windows = {
|
||||||
// ----------
|
get focused() {
|
||||||
get focused() {
|
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||||
var browserWindow = windows.focused;
|
.getService(Ci.nsIWindowMediator);
|
||||||
if (browserWindow)
|
var chromeWindow = wm.getMostRecentWindow("navigator:browser");
|
||||||
return browserWindow.getFocusedTab();
|
/* Utils.log( trackedWindows ) */
|
||||||
return null;
|
if (chromeWindow)
|
||||||
},
|
return trackedWindows.get(chromeWindow);
|
||||||
|
return null;
|
||||||
// ----------
|
|
||||||
open: function open(url, inBackground) {
|
|
||||||
if(typeof(inBackground) == 'undefined')
|
|
||||||
inBackground = false;
|
|
||||||
|
|
||||||
var browserWindow = windows.focused;
|
|
||||||
// TODO: What to do if we have no focused window?
|
|
||||||
// make a new one?
|
|
||||||
|
|
||||||
var tab = browserWindow.addTab(url);
|
|
||||||
if (!inBackground)
|
|
||||||
browserWindow.selectedTab = tab; // TODO doesn't seem to be working
|
|
||||||
|
|
||||||
return tab;
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
tab: function tab(value) {
|
|
||||||
// assuming value is a DOM element for the time being
|
|
||||||
var result = $(value).data('tab');
|
|
||||||
if(!result)
|
|
||||||
result = $(value).find("canvas").data("link").tab;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
toString: function toString() {
|
|
||||||
return "[Tabs]";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var tabsMixIns = new EventListenerMixIns(tabs);
|
|
||||||
tabsMixIns.add({name: "onReady"});
|
|
||||||
tabsMixIns.add({name: "onFocus"});
|
|
||||||
tabsMixIns.add({name: "onClose"});
|
|
||||||
tabsMixIns.add({name: "onOpen"});
|
|
||||||
|
|
||||||
tabs.__proto__ = trackedTabs.values;
|
|
||||||
/* Utils.log(tabs); */
|
|
||||||
|
|
||||||
function newBrowserTab(tabbrowser, chromeTab) {
|
|
||||||
var browserTab = new BrowserTab(tabbrowser, chromeTab);
|
|
||||||
trackedTabs.set(chromeTab, browserTab);
|
|
||||||
return browserTab;
|
|
||||||
}
|
|
||||||
|
|
||||||
function unloadBrowserTab(chromeTab) {
|
|
||||||
var browserTab = trackedTabs.get(chromeTab);
|
|
||||||
trackedTabs.remove(chromeTab);
|
|
||||||
browserTab._unload();
|
|
||||||
}
|
|
||||||
|
|
||||||
function BrowserWindow(chromeWindow) {
|
|
||||||
var tabbrowser = chromeWindow.getBrowser();
|
|
||||||
|
|
||||||
for (var i = 0; i < tabbrowser.tabContainer.itemCount; i++)
|
|
||||||
newBrowserTab(tabbrowser,
|
|
||||||
tabbrowser.tabContainer.getItemAtIndex(i));
|
|
||||||
|
|
||||||
const EVENTS_TO_WATCH = ["TabOpen", "TabMove", "TabClose", "TabSelect"];
|
|
||||||
|
|
||||||
function onEvent(event) {
|
|
||||||
// TODO: For some reason, exceptions that are raised outside of this
|
|
||||||
// function get eaten, rather than logged, so we're adding our own
|
|
||||||
// error logging here.
|
|
||||||
try {
|
|
||||||
// This is a XUL <tab> element of class tabbrowser-tab.
|
|
||||||
var chromeTab = event.originalTarget;
|
|
||||||
|
|
||||||
switch (event.type) {
|
|
||||||
case "TabSelect":
|
|
||||||
tabsMixIns.bubble("onFocus",
|
|
||||||
trackedTabs.get(chromeTab),
|
|
||||||
true);
|
|
||||||
break;
|
|
||||||
case "TabOpen":
|
|
||||||
newBrowserTab(tabbrowser, chromeTab);
|
|
||||||
tabsMixIns.bubble("onOpen",
|
|
||||||
trackedTabs.get(chromeTab),
|
|
||||||
true);
|
|
||||||
break;
|
|
||||||
case "TabMove":
|
|
||||||
break;
|
|
||||||
case "TabClose":
|
|
||||||
tabsMixIns.bubble("onClose",
|
|
||||||
trackedTabs.get(chromeTab),
|
|
||||||
true);
|
|
||||||
unloadBrowserTab(chromeTab);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
Utils.log(e);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
windows.__proto__ = trackedWindows.values;
|
||||||
|
|
||||||
|
var tabs = {
|
||||||
|
// ----------
|
||||||
|
get focused() {
|
||||||
|
var browserWindow = windows.focused;
|
||||||
|
if (browserWindow)
|
||||||
|
return browserWindow.getFocusedTab();
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
open: function open(url, inBackground) {
|
||||||
|
if(typeof(inBackground) == 'undefined')
|
||||||
|
inBackground = false;
|
||||||
|
|
||||||
|
var browserWindow = windows.focused;
|
||||||
|
// TODO: What to do if we have no focused window?
|
||||||
|
// make a new one?
|
||||||
|
|
||||||
|
var tab = browserWindow.addTab(url);
|
||||||
|
if (!inBackground)
|
||||||
|
browserWindow.selectedTab = tab; // TODO doesn't seem to be working
|
||||||
|
|
||||||
|
return tab;
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
tab: function tab(value) {
|
||||||
|
// assuming value is a DOM element for the time being
|
||||||
|
var result = $(value).data('tab');
|
||||||
|
if(!result)
|
||||||
|
result = $(value).find("canvas").data("link").tab;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
toString: function toString() {
|
||||||
|
return "[Tabs]";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var tabsMixIns = new EventListenerMixIns(tabs);
|
||||||
|
tabsMixIns.add({name: "onReady"});
|
||||||
|
tabsMixIns.add({name: "onFocus"});
|
||||||
|
tabsMixIns.add({name: "onClose"});
|
||||||
|
tabsMixIns.add({name: "onOpen"});
|
||||||
|
|
||||||
|
tabs.__proto__ = trackedTabs.values;
|
||||||
|
/* Utils.log(tabs); */
|
||||||
|
|
||||||
|
function newBrowserTab(tabbrowser, chromeTab) {
|
||||||
|
var browserTab = new BrowserTab(tabbrowser, chromeTab);
|
||||||
|
trackedTabs.set(chromeTab, browserTab);
|
||||||
|
return browserTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVENTS_TO_WATCH.forEach(
|
function unloadBrowserTab(chromeTab) {
|
||||||
function(eventType) {
|
var browserTab = trackedTabs.get(chromeTab);
|
||||||
tabbrowser.tabContainer.addEventListener(eventType, onEvent, true);
|
trackedTabs.remove(chromeTab);
|
||||||
|
browserTab._unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function BrowserWindow(chromeWindow) {
|
||||||
|
var tabbrowser = chromeWindow.getBrowser();
|
||||||
|
|
||||||
|
for (var i = 0; i < tabbrowser.tabContainer.itemCount; i++)
|
||||||
|
newBrowserTab(tabbrowser,
|
||||||
|
tabbrowser.tabContainer.getItemAtIndex(i));
|
||||||
|
|
||||||
|
const EVENTS_TO_WATCH = ["TabOpen", "TabMove", "TabClose", "TabSelect"];
|
||||||
|
|
||||||
|
function onEvent(event) {
|
||||||
|
// TODO: For some reason, exceptions that are raised outside of this
|
||||||
|
// function get eaten, rather than logged, so we're adding our own
|
||||||
|
// error logging here.
|
||||||
|
try {
|
||||||
|
// This is a XUL <tab> element of class tabbrowser-tab.
|
||||||
|
var chromeTab = event.originalTarget;
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case "TabSelect":
|
||||||
|
tabsMixIns.bubble("onFocus",
|
||||||
|
trackedTabs.get(chromeTab),
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case "TabOpen":
|
||||||
|
newBrowserTab(tabbrowser, chromeTab);
|
||||||
|
tabsMixIns.bubble("onOpen",
|
||||||
|
trackedTabs.get(chromeTab),
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case "TabMove":
|
||||||
|
break;
|
||||||
|
case "TabClose":
|
||||||
|
tabsMixIns.bubble("onClose",
|
||||||
|
trackedTabs.get(chromeTab),
|
||||||
|
true);
|
||||||
|
unloadBrowserTab(chromeTab);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Utils.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EVENTS_TO_WATCH.forEach(
|
||||||
|
function(eventType) {
|
||||||
|
tabbrowser.tabContainer.addEventListener(eventType, onEvent, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addTab = function addTab(url) {
|
||||||
|
var chromeTab = tabbrowser.addTab(url);
|
||||||
|
// The TabOpen event has just been triggered, so we
|
||||||
|
// just need to fetch it from our dictionary now.
|
||||||
|
return trackedTabs.get(chromeTab);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getFocusedTab = function getFocusedTab() {
|
||||||
|
return trackedTabs.get(tabbrowser.selectedTab);
|
||||||
|
};
|
||||||
|
|
||||||
|
Extension.addUnloadMethod(
|
||||||
|
this,
|
||||||
|
function() {
|
||||||
|
EVENTS_TO_WATCH.forEach(
|
||||||
|
function(eventType) {
|
||||||
|
tabbrowser.tabContainer.removeEventListener(eventType, onEvent, true);
|
||||||
|
});
|
||||||
|
for (var i = 0; i < tabbrowser.tabContainer.itemCount; i++)
|
||||||
|
unloadBrowserTab(tabbrowser.tabContainer.getItemAtIndex(i));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function BrowserTab(tabbrowser, chromeTab) {
|
||||||
|
var browser = chromeTab.linkedBrowser;
|
||||||
|
|
||||||
|
var mixIns = new EventListenerMixIns(this);
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
mixIns.add(
|
||||||
|
{name: "onReady",
|
||||||
|
observe: browser,
|
||||||
|
eventName: "DOMContentLoaded",
|
||||||
|
useCapture: true,
|
||||||
|
bubbleTo: tabsMixIns,
|
||||||
|
filter: function(event) {
|
||||||
|
// Return the document that just loaded.
|
||||||
|
event.tab = self;
|
||||||
|
return event;
|
||||||
|
}});
|
||||||
|
|
||||||
|
mixIns.add(
|
||||||
|
{name: "onFocus",
|
||||||
|
observe: chromeTab,
|
||||||
|
eventName: "TabSelect",
|
||||||
|
useCapture: true,
|
||||||
|
bubbleTo: tabsMixIns,
|
||||||
|
filter: function(event) {
|
||||||
|
// There's not really much to report here other
|
||||||
|
// than the Tab itself, but that's already the
|
||||||
|
// 'this' variable, so just return true for now.
|
||||||
|
return true;
|
||||||
|
}});
|
||||||
|
|
||||||
|
this.__proto__ = {
|
||||||
|
get isClosed() { return (browser == null); },
|
||||||
|
|
||||||
|
get url() {
|
||||||
|
if (browser && browser.currentURI)
|
||||||
|
return browser.currentURI.spec;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
get favicon() {
|
||||||
|
if (chromeTab && chromeTab.image) {
|
||||||
|
return chromeTab.image;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
get contentWindow() {
|
||||||
|
if (browser && browser.contentWindow)
|
||||||
|
return browser.contentWindow;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
get contentDocument() {
|
||||||
|
if (browser && browser.contentDocument)
|
||||||
|
return browser.contentDocument;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
get raw() { return chromeTab; },
|
||||||
|
|
||||||
|
focus: function focus() {
|
||||||
|
if (browser)
|
||||||
|
tabbrowser.selectedTab = chromeTab;
|
||||||
|
},
|
||||||
|
|
||||||
|
close: function close() {
|
||||||
|
if (browser)
|
||||||
|
browser.contentWindow.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
toString: function toString() {
|
||||||
|
if (!browser)
|
||||||
|
return "[Closed Browser Tab]";
|
||||||
|
else
|
||||||
|
return "[Browser Tab]";
|
||||||
|
},
|
||||||
|
|
||||||
|
_unload: function _unload() {
|
||||||
|
mixIns.unload();
|
||||||
|
mixIns = null;
|
||||||
|
tabbrowser = null;
|
||||||
|
chromeTab = null;
|
||||||
|
browser = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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.addTab = function addTab(url) {
|
this.__defineGetter__("tabs", function() { return tabs; });
|
||||||
var chromeTab = tabbrowser.addTab(url);
|
|
||||||
// The TabOpen event has just been triggered, so we
|
|
||||||
// just need to fetch it from our dictionary now.
|
|
||||||
return trackedTabs.get(chromeTab);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getFocusedTab = function getFocusedTab() {
|
|
||||||
return trackedTabs.get(tabbrowser.selectedTab);
|
|
||||||
};
|
|
||||||
|
|
||||||
Extension.addUnloadMethod(
|
Extension.addUnloadMethod(
|
||||||
this,
|
this,
|
||||||
function() {
|
function() {
|
||||||
EVENTS_TO_WATCH.forEach(
|
tabsMixIns.unload();
|
||||||
function(eventType) {
|
browserWatcher.unload();
|
||||||
tabbrowser.tabContainer.removeEventListener(eventType, onEvent, true);
|
|
||||||
});
|
|
||||||
for (var i = 0; i < tabbrowser.tabContainer.itemCount; i++)
|
|
||||||
unloadBrowserTab(tabbrowser.tabContainer.getItemAtIndex(i));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.Tabs = tabs;
|
||||||
|
window.Tabs.app = XULApp;
|
||||||
|
this._sendToSubscribers('load');
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function BrowserTab(tabbrowser, chromeTab) {
|
// ----------
|
||||||
var browser = chromeTab.linkedBrowser;
|
window.TabsManager.init();
|
||||||
|
|
||||||
var mixIns = new EventListenerMixIns(this);
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
mixIns.add(
|
|
||||||
{name: "onReady",
|
|
||||||
observe: browser,
|
|
||||||
eventName: "DOMContentLoaded",
|
|
||||||
useCapture: true,
|
|
||||||
bubbleTo: tabsMixIns,
|
|
||||||
filter: function(event) {
|
|
||||||
// Return the document that just loaded.
|
|
||||||
event.tab = self;
|
|
||||||
return event;
|
|
||||||
}});
|
|
||||||
|
|
||||||
mixIns.add(
|
|
||||||
{name: "onFocus",
|
|
||||||
observe: chromeTab,
|
|
||||||
eventName: "TabSelect",
|
|
||||||
useCapture: true,
|
|
||||||
bubbleTo: tabsMixIns,
|
|
||||||
filter: function(event) {
|
|
||||||
// There's not really much to report here other
|
|
||||||
// than the Tab itself, but that's already the
|
|
||||||
// 'this' variable, so just return true for now.
|
|
||||||
return true;
|
|
||||||
}});
|
|
||||||
|
|
||||||
this.__proto__ = {
|
|
||||||
get isClosed() { return (browser == null); },
|
|
||||||
|
|
||||||
get url() {
|
|
||||||
if (browser && browser.currentURI)
|
|
||||||
return browser.currentURI.spec;
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
get favicon() {
|
|
||||||
if (chromeTab && chromeTab.image) {
|
|
||||||
return chromeTab.image;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
get contentWindow() {
|
|
||||||
if (browser && browser.contentWindow)
|
|
||||||
return browser.contentWindow;
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
get contentDocument() {
|
|
||||||
if (browser && browser.contentDocument)
|
|
||||||
return browser.contentDocument;
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
get raw() { return chromeTab; },
|
|
||||||
|
|
||||||
focus: function focus() {
|
|
||||||
if (browser)
|
|
||||||
tabbrowser.selectedTab = chromeTab;
|
|
||||||
},
|
|
||||||
|
|
||||||
close: function close() {
|
|
||||||
if (browser)
|
|
||||||
browser.contentWindow.close();
|
|
||||||
},
|
|
||||||
|
|
||||||
toString: function toString() {
|
|
||||||
if (!browser)
|
|
||||||
return "[Closed Browser Tab]";
|
|
||||||
else
|
|
||||||
return "[Browser Tab]";
|
|
||||||
},
|
|
||||||
|
|
||||||
_unload: function _unload() {
|
|
||||||
mixIns.unload();
|
|
||||||
mixIns = null;
|
|
||||||
tabbrowser = null;
|
|
||||||
chromeTab = null;
|
|
||||||
browser = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = new Tabs().tabs;
|
|
||||||
window.Tabs.app = XULApp;
|
|
||||||
})();
|
})();
|
Loading…
Reference in New Issue
Block a user