home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Minami 80
/
MINAMI80.iso
/
Extra
/
DivXInstaller.exe
/
$PLUGINSDIR
/
GoogleToolbarFirefox.msi
/
xpi
/
amulet-jslib
/
firefox
/
tabbedbrowserwatcher.js
< prev
next >
Wrap
Text File
|
2006-05-15
|
11KB
|
337 lines
function G_TabbedBrowserWatcher(tabBrowser, name, opt_filterAboutBlank) {
this.debugZone = "tabbedbrowserwatcher";
this.tabBrowser_ = tabBrowser;
this.filterAboutBlank_ = !!opt_filterAboutBlank;
this.events = G_TabbedBrowserWatcher.events; // Convenience pointer
G_Assert(this, typeof name == "string" && !!name,
"Need a probabilistically unique name");
this.name_ = name;
this.mark_ = G_TabbedBrowserWatcher.mark_ + "-" + this.name_;
this.registrar_ = new EventRegistrar(G_TabbedBrowserWatcher.events);
this.tabbox_ = this.getTabBrowser().mTabBox;
this.onDOMContentLoadedClosure_ = BindToObject(this.onDOMContentLoaded, this)
this.tabbox_.addEventListener("DOMContentLoaded",
this.onDOMContentLoadedClosure_, true);
this.onDOMNodeInsertedClosure_ = BindToObject(this.onDOMNodeInserted, this);
this.tabbox_.addEventListener("DOMNodeInserted",
this.onDOMNodeInsertedClosure_, true);
this.onTabSwitchClosure_ = BindToObject(this.onTabSwitch, this);
this.tabbox_.addEventListener("select",
this.onTabSwitchClosure_, true);
var win = this.tabbox_.ownerDocument.defaultView;
this.onChromeUnloadClosure_ = BindToObject(this.onChromeUnload_, this);
win.addEventListener('unload', this.onChromeUnloadClosure_, false);
this.lastTab_ = this.getCurrentBrowser();
this.detectNewTabs_();
}
G_TabbedBrowserWatcher.events = {
DOMCONTENTLOADED: "domcontentloaded",
LOCATIONCHANGE: "locationchange",
PAGESHOW: "pageshow",
PAGEHIDE: "pagehide",
LOAD: "load",
UNLOAD: "unload",
TABLOAD: "tabload",
TABUNLOAD: "tabunload",
TABSWITCH: "tabswitch",
TABMOVE: "tabmove",
};
G_TabbedBrowserWatcher.mark_ = "watcher-marked";
G_TabbedBrowserWatcher.prototype.onChromeUnload_ = function(event) {
G_Debug(this, "Removing event listeners");
if (this.tabbox_) {
this.tabbox_.removeEventListener("DOMContentLoaded",
this.onDOMContentLoadedClosure_, true);
this.tabbox_.removeEventListener("DOMNodeInserted",
this.onDOMNodeInsertedClosure_, true);
this.tabbox_.removeEventListener("select",
this.onTabSwitchClosure_, true);
var win = this.tabbox_.ownerDocument.defaultView;
win.removeEventListener('unload', this.onChromeUnloadClosure_, false);
this.tabbox_ = null;
}
if (this.lastTab_) {
this.lastTab_ = null;
}
if (this.tabBrowser_) {
this.tabBrowser_ = null;
}
}
G_TabbedBrowserWatcher.prototype.isInstrumented_ = function(browser) {
return !!browser[this.mark_];
}
G_TabbedBrowserWatcher.prototype.instrumentBrowser_ = function(browser) {
G_Assert(this, !this.isInstrumented_(browser),
"Browser already instrumented!");
new G_BrowserWatcher(this, browser);
browser[this.mark_] = true;
}
G_TabbedBrowserWatcher.prototype.detectNewTabs_ = function() {
var tb = this.getTabBrowser();
for (var i = 0; i < tb.browsers.length; ++i)
this.maybeFireTabLoad(tb.browsers[i]);
}
G_TabbedBrowserWatcher.prototype.registerListener = function(eventType,
listener) {
this.registrar_.registerListener(eventType, listener);
}
G_TabbedBrowserWatcher.prototype.removeListener = function(eventType,
listener) {
this.registrar_.removeListener(eventType, listener);
}
G_TabbedBrowserWatcher.prototype.fire = function(eventType, e) {
this.registrar_.fire(eventType, e);
}
G_TabbedBrowserWatcher.prototype.fireDocEvent_ = function(eventType,
doc,
browser) {
if (!this.tabBrowser_) {
G_Debug(this, "Firing event after shutdown: " + eventType);
return;
}
try {
var isTop = (doc == browser.contentDocument);
} catch(e) {
var isTop = undefined;
}
var inSelected = (browser == this.getCurrentBrowser());
var location = doc ? doc.location.href : undefined;
if (!this.filterAboutBlank_ || location != "about:blank") {
G_Debug(this, "firing " + eventType + " for " + location +
(isTop ? " (isTop)" : "") + (inSelected ? " (inSelected)" : ""));
this.fire(eventType, { "doc": doc,
"isTop": isTop,
"inSelected": inSelected,
"browser": browser});
}
}
G_TabbedBrowserWatcher.prototype.maybeFireTabLoad = function(browser) {
if (!this.isInstrumented_(browser)) { // Is it a new browser?
this.instrumentBrowser_(browser); // Add a G_BrowserWatcher
G_Debug(this, "firing tabload");
this.fire(this.events.TABLOAD, { "browser": browser });
}
}
G_TabbedBrowserWatcher.prototype.onDOMContentLoaded = function(e) {
G_Debug(this, "onDOMContentLoaded for a " + e.target);
var doc = e.target;
var browser = this.getBrowserFromDocument(doc);
if (!browser) {
G_Debug(this, "domcontentloaded: no browser for " + doc.location.href);
return;
}
this.maybeFireTabLoad(browser);
G_Debug(this, "DOMContentLoaded broken for forward/back buttons.");
this.fireDocEvent_(this.events.DOMCONTENTLOADED, doc, browser);
}
G_TabbedBrowserWatcher.prototype.onDOMNodeInserted = function(e) {
G_Debug(this, "onDOMNodeInserted for a " + e.target +
" related: " + e.relatedNode);
if (e.target.localName != "tab") {
return;
}
if (!isDef(e.target._tPos)) {
return;
}
var fromPos = e.target._tPos;
var toPos;
for (var i = 0; i < e.relatedNode.childNodes.length; i++) {
var child = e.relatedNode.childNodes[i];
if (child == e.target) {
toPos = i;
break;
}
}
G_Debug(this, "firing tabmove");
this.fire(this.events.TABMOVE, { "tab": e.target,
"fromIndex": fromPos,
"toIndex": toPos } );
}
G_TabbedBrowserWatcher.prototype.onTabSwitch = function(e) {
if (e.target == null ||
(e.target.localName != "tabs" && e.target.localName != "tabpanels"))
return;
var fromBrowser = this.lastTab_;
var toBrowser = this.getCurrentBrowser();
if (fromBrowser != toBrowser) {
this.lastTab_ = toBrowser;
G_Debug(this, "firing tabswitch");
this.fire(this.events.TABSWITCH, { "fromBrowser": fromBrowser,
"toBrowser": toBrowser });
}
}
G_TabbedBrowserWatcher.prototype.getTabBrowser = function() {
return this.tabBrowser_;
}
G_TabbedBrowserWatcher.prototype.getCurrentBrowser = function() {
return this.getTabBrowser().selectedBrowser;
}
G_TabbedBrowserWatcher.prototype.getCurrentWindow = function() {
return this.getCurrentBrowser().contentWindow;
}
G_TabbedBrowserWatcher.prototype.getBrowserFromDocument = function(doc) {
function docInWindow(doc, win) {
if (win.document == doc)
return true;
if (win.frames)
for (var i = 0; i < win.frames.length; i++)
if (docInWindow(doc, win.frames[i]))
return true;
return false;
}
var browsers = this.getTabBrowser().browsers;
for (var i = 0; i < browsers.length; i++)
if (docInWindow(doc, browsers[i].contentWindow))
return browsers[i];
return null;
}
G_TabbedBrowserWatcher.prototype.getDocumentFromURL = function(url,
opt_browser) {
function docWithURL(win, url) {
if (win.document.location.href == url)
return win.document;
if (win.frames)
for (var i = 0; i < win.frames.length; i++) {
var rv = docWithURL(win.frames[i], url);
if (rv)
return rv;
}
return null;
}
if (opt_browser)
return docWithURL(opt_browser.contentWindow, url);
var browsers = this.getTabBrowser().browsers;
for (var i=0; i < browsers.length; i++) {
var rv = docWithURL(browsers[i].contentWindow, url);
if (rv)
return rv;
}
return null;
}
G_TabbedBrowserWatcher.prototype.getDocumentsFromURL = function(url,
opt_browser) {
var docs = [];
function getDocsWithURL(win, url) {
if (win.document.location.href == url)
docs.push(win.document);
if (win.frames)
for (var i = 0; i < win.frames.length; i++)
getDocsWithURL(win.frames[i], url);
}
if (opt_browser)
return getDocsWithURL(opt_browser.contentWindow, url);
var browsers = this.getTabBrowser().browsers;
for (var i=0; i < browsers.length; i++)
getDocsWithURL(browsers[i].contentWindow, url);
return docs;
}
G_TabbedBrowserWatcher.prototype.getBrowserFromWindow = function(sub) {
function containsSubWindow(sub, win) {
if (win == sub)
return true;
if (win.frames)
for (var i=0; i < win.frames.length; i++)
if (containsSubWindow(sub, win.frames[i]))
return true;
return false;
}
var browsers = this.getTabBrowser().browsers;
for (var i=0; i < browsers.length; i++)
if (containsSubWindow(sub, browsers[i].contentWindow))
return browsers[i];
return null;
}
G_TabbedBrowserWatcher.getTabElementFromBrowser = function(tabBrowser,
browser) {
for (var i=0; i < tabBrowser.browsers.length; i++)
if (tabBrowser.browsers[i] == browser)
return tabBrowser.mTabContainer.childNodes[i];
return null;
}
if (G_GDEBUG) {
G_debugService.loggifier.loggify(G_TabbedBrowserWatcher.prototype);
}
function G_BrowserWatcher(tabbedBrowserWatcher, browser) {
this.debugZone = "browserwatcher";
this.parent_ = tabbedBrowserWatcher;
this.browser_ = browser;
this.onPageShowClosure_ = BindToObject(this.onPageShow, this);
this.browser_.addEventListener("pageshow", this.onPageShowClosure_, true);
this.onPageHideClosure_ = BindToObject(this.onPageHide, this);
this.browser_.addEventListener("pagehide", this.onPageHideClosure_, true);
this.onLoadClosure_ = BindToObject(this.onLoad, this);
this.browser_.addEventListener("load", this.onLoadClosure_, true);
this.onUnloadClosure_ = BindToObject(this.onUnload, this);
this.browser_.addEventListener("unload", this.onUnloadClosure_, true);
this.webProgressListener_ = {
QueryInterface: function() { return this; },
onLocationChange: bind(this.onLocationChange, this),
onStateChange: function(){},
onStatusChange: function(){},
onSecurityChange: function(){},
onProgressChange: function(){}
};
G_Debug(this, "adding progress listener");
this.browser_.addProgressListener(this.webProgressListener_,
Ci.nsIWebProgress.NOTIFY_LOCATION);
G_Debug(this, "Done");
}
G_BrowserWatcher.prototype.onLocationChange = function(webProgress,
request, location) {
G_Debug(this, "onLocationChange for {%s}".subs(location.spec));
if (!this.parent_) {
G_Debug(this, "onLocationChange after tab close");
return;
}
var e = { browser: this.browser_,
isTop: true };
this.parent_.fire(this.parent_.events.LOCATIONCHANGE, e);
}
G_BrowserWatcher.prototype.onPageShow = function(e) {
G_Debug(this, "onPageShow for " + ((e.target) ? (e.target) : ("undefined")));
if (e.target && e.target.nodeName == "#document") {
var doc = e.target;
this.parent_.fireDocEvent_(this.parent_.events.PAGESHOW,
doc,
this.browser_);
}
}
G_BrowserWatcher.prototype.onLoad = function(e) {
G_Debug(this, "onLoad for a " + e.target);
if (!e.target) {
G_Debug(this, "e.target is null; canceling onload event");
return;
}
if (e.target.nodeName != "#document")
return;
var doc = e.target;
this.parent_.fireDocEvent_(this.parent_.events.LOAD, doc, this.browser_);
}
G_BrowserWatcher.prototype.onUnload = function(e) {
G_Debug(this, "onUnload for " + ((e.target) ? (e.target) : ("undefined")));
var doc = e.target;
if (doc && doc.nodeName == "#document")
this.parent_.fireDocEvent_("unload", doc, this.browser_);
if (!doc) { // This is a closing tab
G_Debug(this, "firing tabunload for a " + this.browser_ + "(" +
this.browser_.nodename + ")");
this.parent_.fire(this.parent_.events.TABUNLOAD,
{ "browser": this.browser_ });
this.browser_.removeEventListener("pageshow", this.onPageShowClosure_, true);
this.browser_.removeEventListener("pagehide", this.onPageHideClosure_, true);
this.browser_.removeEventListener("load", this.onLoadClosure_, true);
this.browser_.removeEventListener("unload", this.onUnloadClosure_, true);
this.parent_ = null;
this.browser_ = null;
G_Debug(this, "Removed event listeners");
}
}
G_BrowserWatcher.prototype.onPageHide = function(e) {
G_Debug(this, "onPageHide for a " + e.target + "(" +
e.target.nodeName + ")");
if (e.target.nodeName != "#document") // Ignore non-documents
return;
var doc = e.target;
this.parent_.fireDocEvent_(this.parent_.events.PAGEHIDE, doc, this.browser_);
}