Bug 337741 (for tony@ponderer.org) r=brettw a=bryner safe browsing doesn't need to listen to so many events

This commit is contained in:
brettw%gmail.com 2006-05-15 20:28:08 +00:00
parent 59c1139c5e
commit f682c72ab5
4 changed files with 40 additions and 301 deletions

View File

@ -378,13 +378,3 @@ PROT_Controller.prototype.onTabSwitch = function(e) {
PROT_Controller.prototype.loadURI = function(browser, url) { PROT_Controller.prototype.loadURI = function(browser, url) {
browser.loadURI(url, null, null); browser.loadURI(url, null, null);
} }
/**
* Reload the current page in the given browser
*
* @param browser Browser which to reload
*/
PROT_Controller.prototype.reloadPage = function(browser) {
var normalReload = browser.webNavigation.LOAD_FLAGS_NORMAL;
browser.reload(normalReload);
}

View File

@ -85,23 +85,17 @@
* The NavWatcher abstracts listening for progresslistener-based * The NavWatcher abstracts listening for progresslistener-based
* notifications. * notifications.
* *
* @param opt_filterSpurious Boolean indicating whether to filter events
* for navigations to docs about which you
* probably don't care, such as about:blank,
* chrome://, and file:// URLs.
*
* @constructor * @constructor
*/ */
function G_NavWatcher(opt_filterSpurious) { function G_NavWatcher() {
this.debugZone = "navwatcher"; this.debugZone = "navwatcher";
this.filterSpurious_ = !!opt_filterSpurious;
this.events = G_NavWatcher.events; // Convenience pointer this.events = G_NavWatcher.events; // Convenience pointer
this.registrar_ = new EventRegistrar(this.events); this.registrar_ = new EventRegistrar(this.events);
var wp = Ci.nsIWebProgress; var wp = Ci.nsIWebProgress;
var wpService = Cc["@mozilla.org/docloaderservice;1"].getService(wp); var wpService = Cc["@mozilla.org/docloaderservice;1"].getService(wp);
wpService.addProgressListener(this, wp.NOTIFY_STATE_ALL); wpService.addProgressListener(this, wp.NOTIFY_STATE_REQUEST);
} }
// Events for which listeners can register. Future additions could include // Events for which listeners can register. Future additions could include
@ -169,9 +163,9 @@ G_NavWatcher.prototype.fire = function(eventType, e) {
G_NavWatcher.prototype.isSpurious_ = function(url) { G_NavWatcher.prototype.isSpurious_ = function(url) {
return (url == "about:blank" || return (url == "about:blank" ||
url == "about:config" || url == "about:config" ||
url.indexOf("chrome://") == 0 || url.startsWith("chrome://") ||
url.indexOf("file://") == 0 || url.startsWith("file://") ||
url.indexOf("jar:") == 0); url.startsWith("jar:"));
} }
/** /**
@ -218,8 +212,7 @@ G_NavWatcher.prototype.onStateChange = function(webProgress,
url = request.name; url = request.name;
} catch(e) { return; } } catch(e) { return; }
if (!this.filterSpurious_ || !this.isSpurious_(url)) { if (!this.isSpurious_(url)) {
G_Debug(this, "firing docnavstart for " + url); G_Debug(this, "firing docnavstart for " + url);
var eventObj = { var eventObj = {
"request": request, "request": request,
@ -230,8 +223,9 @@ G_NavWatcher.prototype.onStateChange = function(webProgress,
} }
} }
// We don't care about the other kinds of updates, but we need to // We don't care about the other kinds of updates (and won't get them since we
// implement the interface anyway. // only signed up for state requests), but we should implement the interface
// anyway.
/** /**
* NOP * NOP

View File

@ -215,25 +215,6 @@ function G_TabbedBrowserWatcher(tabBrowser, name, opt_filterAboutBlank) {
this.tabbox_ = this.getTabBrowser().mTabBox; this.tabbox_ = this.getTabBrowser().mTabBox;
// We watch for events occuring in previously unseen browsers at
// this (the tabbedbrowser) level, and attach listeners to the new
// browsers when we see them. In order to do this properly, we need
// to watch for the earliest event we're interested in
// (DOMContentLoaded), because otherwise we'd miss this event in newly
// opening browsers. For example, if instead we hooked load here,
// DOMContentLoaded would already have passed by the time we noticed
// there was a new browser.
this.onDOMContentLoadedClosure_ = BindToObject(this.onDOMContentLoaded, this)
this.tabbox_.addEventListener("DOMContentLoaded",
this.onDOMContentLoadedClosure_, true);
// We watch for DOM nodes inserted under the tabbox so we can detect when
// a user drags a tab to a new location.
this.onDOMNodeInsertedClosure_ = BindToObject(this.onDOMNodeInserted, this);
this.tabbox_.addEventListener("DOMNodeInserted",
this.onDOMNodeInsertedClosure_, true);
// There's no tabswitch event in Firefox, so we fake it by watching // There's no tabswitch event in Firefox, so we fake it by watching
// for selects on the tabbox. // for selects on the tabbox.
this.onTabSwitchClosure_ = BindToObject(this.onTabSwitch, this); this.onTabSwitchClosure_ = BindToObject(this.onTabSwitch, this);
@ -242,22 +223,11 @@ function G_TabbedBrowserWatcher(tabBrowser, name, opt_filterAboutBlank) {
// Used to determine when the user has switched tabs // Used to determine when the user has switched tabs
this.lastTab_ = this.getCurrentBrowser(); this.lastTab_ = this.getCurrentBrowser();
// Ensure we hook a G_BrowserWatcher to all tabs that are open at startup
this.detectNewTabs_();
} }
// Events for which listeners can register // Events for which listeners can register
G_TabbedBrowserWatcher.events = { G_TabbedBrowserWatcher.events = {
DOMCONTENTLOADED: "domcontentloaded",
PAGESHOW: "pageshow",
PAGEHIDE: "pagehide",
LOAD: "load",
UNLOAD: "unload",
TABLOAD: "tabload",
TABUNLOAD: "tabunload",
TABSWITCH: "tabswitch", TABSWITCH: "tabswitch",
TABMOVE: "tabmove",
}; };
// We mark new tabs as we see them // We mark new tabs as we see them
@ -269,10 +239,6 @@ G_TabbedBrowserWatcher.mark_ = "watcher-marked";
G_TabbedBrowserWatcher.prototype.shutdown = function() { G_TabbedBrowserWatcher.prototype.shutdown = function() {
G_Debug(this, "Removing event listeners"); G_Debug(this, "Removing event listeners");
if (this.tabbox_) { if (this.tabbox_) {
this.tabbox_.removeEventListener("DOMContentLoaded",
this.onDOMContentLoadedClosure_, true);
this.tabbox_.removeEventListener("DOMNodeInserted",
this.onDOMNodeInsertedClosure_, true);
this.tabbox_.removeEventListener("select", this.tabbox_.removeEventListener("select",
this.onTabSwitchClosure_, true); this.onTabSwitchClosure_, true);
// Break circular ref so we can be gc'ed. // Break circular ref so we can be gc'ed.
@ -313,16 +279,6 @@ G_TabbedBrowserWatcher.prototype.instrumentBrowser_ = function(browser) {
browser[this.mark_] = true; browser[this.mark_] = true;
} }
/**
* Attach BrowserWatchers to all open, unseen tabs
*/
G_TabbedBrowserWatcher.prototype.detectNewTabs_ = function() {
var tb = this.getTabBrowser();
for (var i = 0; i < tb.browsers.length; ++i)
this.maybeFireTabLoad(tb.browsers[i]);
}
/** /**
* Register to receive events of a particular type * Register to receive events of a particular type
* *
@ -404,85 +360,6 @@ G_TabbedBrowserWatcher.prototype.fireDocEvent_ = function(eventType,
} }
} }
/**
* Invoked on a browser to ensure we've seen it before. If we haven't,
* the browser is instrumented and the tabload event is fired.
*
* @param browser Reference to the browser to check
*/
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");
// And shoot notification
this.fire(this.events.TABLOAD, { "browser": browser });
}
}
/**
* Invoked when the document content has loaded for a document. Externally
* linked in content might not yet have loaded.
*
* @param e Event object
*/
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);
}
/**
* Invoked when a new xul node is inserted under the tabbox. We use this
* to detect tab moves.
*
* @param e Event object
*/
G_TabbedBrowserWatcher.prototype.onDOMNodeInserted = function(e) {
G_Debug(this, "onDOMNodeInserted for a " + e.target +
" related: " + e.relatedNode);
// Ignore the node insertion if it isn't a tab
if (e.target.localName != "tab") {
return;
}
// If the tab was just inserted (it's a new tab, not a moved tab), the
// pos value will be undefined.
if (!isDef(e.target._tPos)) {
return;
}
// Get the target tab's old position
var fromPos = e.target._tPos;
// Get the target tab's new position.
// Would like to avoid a linear search through the tabs but I'm not sure
// how to get around this.
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 } );
}
/** /**
* Invoked when the user might have switched tabs * Invoked when the user might have switched tabs
* *
@ -692,119 +569,3 @@ G_TabbedBrowserWatcher.getTabElementFromBrowser = function(tabBrowser,
return null; return null;
} }
if (G_GDEBUG) {
G_debugService.loggifier.loggify(G_TabbedBrowserWatcher.prototype);
}
/**
* The G_TabbedBrowserWatcher delegates watching most events in browsers
* to this object. It calls into its parent (the G_TabbedBrowserWatcher)
* to signal events and is garbage collected when the browser goes away
* because we don't hold a reference to it.
*
* @constructor
* @param tabbedBrowserWatcher The high-level watcher through which we
* should send notifications
* @param browser The browser to which we should attach
*/
function G_BrowserWatcher(tabbedBrowserWatcher, browser) {
this.debugZone = "browserwatcher";
this.parent_ = tabbedBrowserWatcher;
this.browser_ = browser;
G_Debug(this, "new G_BrowserWatcher");
// Now register to hear most of the doc-related events
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);
}
/**
* Invoked when pageshow fires
*
* @param e Event object passed in by event system
*/
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_);
}
}
/**
* Invoked when load fires
*
* @param e Event object passed in by event system
*/
G_BrowserWatcher.prototype.onLoad = function(e) {
G_Debug(this, "onLoad for a " + e.target);
if (e.target.nodeName != "#document")
return;
var doc = e.target;
this.parent_.fireDocEvent_(this.parent_.events.LOAD, doc, this.browser_);
}
/**
* Invoked when unload fires
*
* @param e Event object passed in by event system
*/
G_BrowserWatcher.prototype.onUnload = function(e) {
G_Debug(this, "onUnload for " + ((e.target) ? (e.target) : ("undefined")));
var doc = e.target;
// We get spurious unloads for non-docs :(
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 + ")");
// fire tabunload event
this.parent_.fire(this.parent_.events.TABUNLOAD,
{ "browser": this.browser_ });
// unregister event listeners
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, "Removing event listeners");
}
}
/**
* Invoked when pagehide fires
*
* @param e Event object passed in by event system
*/
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_);
}

View File

@ -89,7 +89,7 @@ function PROT_PhishingWarden() {
// Register w/NavWatcher to hear notifications about requests for docs // Register w/NavWatcher to hear notifications about requests for docs
if (!this.testing_) { if (!this.testing_) {
this.navWatcher_ = new G_NavWatcher(true /* filter spurious navs */); this.navWatcher_ = new G_NavWatcher();
this.navWatcher_.registerListener("docnavstart", this.navWatcher_.registerListener("docnavstart",
BindToObject(this.onDocNavStart, BindToObject(this.onDocNavStart,
this)); this));
@ -237,16 +237,18 @@ PROT_PhishingWarden.prototype.onPhishWardenEnabledPrefChanged = function(
* @param e Event object passed in by the NavWatcher * @param e Event object passed in by the NavWatcher
*/ */
PROT_PhishingWarden.prototype.onDocNavStart = function(e) { PROT_PhishingWarden.prototype.onDocNavStart = function(e) {
if (this.phishWardenEnabled_ !== true) {
return;
}
var url = e.url; var url = e.url;
var request = e.request; var request = e.request;
G_Debug(this, "phishWarden: " + //G_Debug(this, "phishWarden: " +
(this.phishWardenEnabled_ ? "enabled" : "disabled")); // (this.phishWardenEnabled_ ? "enabled" : "disabled"));
G_Debug(this, "checkRemote: " + //G_Debug(this, "checkRemote: " +
(this.checkRemote_ ? "yes" : "no")); // (this.checkRemote_ ? "yes" : "no"));
G_Debug(this, "isTestURL: " + //G_Debug(this, "isTestURL: " +
(this.isBlacklistTestURL(url) ? "yes" : "no")); // (this.isBlacklistTestURL(url) ? "yes" : "no"));
// This logic is a bit involved. In some instances of SafeBrowsing // This logic is a bit involved. In some instances of SafeBrowsing
// (the stand-alone extension, for example), the user might yet have // (the stand-alone extension, for example), the user might yet have
@ -258,24 +260,20 @@ PROT_PhishingWarden.prototype.onDocNavStart = function(e) {
// explicitly disabled. // explicitly disabled.
// If we're on the test page and we're not explicitly disabled // If we're on the test page and we're not explicitly disabled
if (this.isBlacklistTestURL(url) && if (this.isBlacklistTestURL(url)) {
(this.phishWardenEnabled_ === true ||
this.phishWardenEnabled_ === null)) {
this.houstonWeHaveAProblem_(request); this.houstonWeHaveAProblem_(request);
} else if (this.phishWardenEnabled_ === true) { }
// We're enabled. Either send a request off or check locally // Either send a request off or check locally
// TODO: move this logic to checkUrl, formalize the error callback if (this.checkRemote_) {
if (this.checkRemote_) { // TODO: Use local whitelists to suppress remote BL lookups.
// TODO: Use local whitelists to suppress remote BL lookups. this.fetcher_.get(url,
this.fetcher_.get(url, BindToObject(this.onTRFetchComplete,
BindToObject(this.onTRFetchComplete, this,
this, request));
request)); } else {
} else { this.checkUrl(url, BindToObject(this.houstonWeHaveAProblem_,
this.checkUrl(url, BindToObject(this.houstonWeHaveAProblem_, this,
this, request));
request));
}
} }
} }
@ -433,20 +431,16 @@ PROT_PhishingWarden.prototype.isBlacklistTestURL = function(url) {
*/ */
PROT_PhishingWarden.prototype.checkUrl = function(url, callback) { PROT_PhishingWarden.prototype.checkUrl = function(url, callback) {
G_Debug(this, "Checking URL for " + url); G_Debug(this, "Checking URL for " + url);
if (this.isBlacklistTestURL(url)) { // We wrap the callback because we also want
// to report the blacklist hit to our data provider.
function evilCallback() {
G_Debug("evilCallback", "Local blacklist hit");
// maybe send a report
(new PROT_Reporter).report("phishblhit", url);
callback(); callback();
} else {
// We wrap the callback because we also want
// to report the blacklist hit to our data provider.
function evilCallback() {
G_Debug("evilCallback", "Local blacklist hit");
// maybe send a report
(new PROT_Reporter).report("phishblhit", url);
callback();
}
// Check the local lists.
this.isEvilURL_(url, evilCallback);
} }
// Check the local lists.
this.isEvilURL_(url, evilCallback);
} }
/** /**