Bug 83265 - Add a way to disable HTTP-EQUIV=refresh. patch from Mark Pilgrim <pilgrim@gmail.com>, r=biesi,mano,mento. sr=bz.

This commit is contained in:
mozilla.mano%sent.com 2007-02-08 13:15:50 +00:00
parent f481640452
commit 6040afd6ff
26 changed files with 468 additions and 97 deletions

View File

@ -546,3 +546,6 @@ pref("browser.sessionstore.postdata", 0);
pref("browser.sessionstore.privacy_level", 1);
// how many tabs can be reopened (per window)
pref("browser.sessionstore.max_tabs_undo", 10);
// allow META refresh by default
pref("accessibility.blockautorefresh", false);

View File

@ -3521,12 +3521,13 @@ nsBrowserStatusHandler.prototype =
QueryInterface : function(aIID)
{
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsIXULBrowserWindow) ||
aIID.equals(Components.interfaces.nsISupports))
if (aIID.equals(Ci.nsIWebProgressListener) ||
aIID.equals(Ci.nsIWebProgressListener2) ||
aIID.equals(Ci.nsISupportsWeakReference) ||
aIID.equals(Ci.nsIXULBrowserWindow) ||
aIID.equals(Ci.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
throw Cr.NS_NOINTERFACE;
},
init : function()
@ -3640,6 +3641,15 @@ nsBrowserStatusHandler.prototype =
}
},
onProgressChange64 : function (aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress,
aCurTotalProgress, aMaxTotalProgress)
{
return this.onProgressChange(aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress,
aMaxTotalProgress);
},
onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
{
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
@ -3887,6 +3897,63 @@ nsBrowserStatusHandler.prototype =
this.updateStatusField();
},
onRefreshAttempted : function(aWebProgress, aURI, aDelay, aSameURI)
{
if (gPrefService.getBoolPref("accessibility.blockautorefresh")) {
var brandBundle = document.getElementById("bundle_brand");
var brandShortName = brandBundle.getString("brandShortName");
var refreshButtonText =
gNavigatorBundle.getString("refreshBlocked.goButton");
var refreshButtonAccesskey =
gNavigatorBundle.getString("refreshBlocked.goButton.accesskey");
var message;
if (aSameURI)
message = gNavigatorBundle.getFormattedString(
"refreshBlocked.refreshLabel", [brandShortName]);
else
message = gNavigatorBundle.getFormattedString(
"refreshBlocked.redirectLabel", [brandShortName]);
var topBrowser = getBrowserFromContentWindow(aWebProgress.DOMWindow.top);
var docShell = aWebProgress.DOMWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
var notificationBox = gBrowser.getNotificationBox(topBrowser);
var notification = notificationBox.getNotificationWithValue(
"refresh-blocked");
if (notification) {
notification.label = message;
notification.refreshURI = aURI;
notification.delay = aDelay;
notification.docShell = docShell;
}
else {
var buttons = [{
label: refreshButtonText,
accessKey: refreshButtonAccesskey,
callback: function(aNotification, aButton) {
var refreshURI = aNotification.docShell
.QueryInterface(Ci.nsIRefreshURI);
refreshURI.forceRefreshURI(aNotification.refreshURI,
aNotification.delay, true);
}
}];
const priority = notificationBox.PRIORITY_INFO_MEDIUM;
notification = notificationBox.appendNotification(
message,
"refresh-blocked",
"chrome://browser/skin/Info.png",
priority,
buttons);
notification.refreshURI = aURI;
notification.delay = aDelay;
notification.docShell = docShell;
}
return false;
}
return true;
},
onSecurityChange : function(aWebProgress, aRequest, aState)
{
const wpl = Components.interfaces.nsIWebProgressListener;

View File

@ -529,3 +529,13 @@ function isElementVisible(aElement)
document.defaultView
.getComputedStyle(aElement, null).visibility == "visible");
}
function getBrowserFromContentWindow(aContentWindow)
{
var browsers = gBrowser.browsers;
for (var i = 0; i < browsers.length; i++) {
if (browsers[i].contentWindow == aContentWindow)
return browsers[i];
}
return null;
}

View File

@ -67,6 +67,7 @@
<!-- General tab -->
<preference id="accessibility.browsewithcaret" name="accessibility.browsewithcaret" type="bool"/>
<preference id="accessibility.typeaheadfind" name="accessibility.typeaheadfind" type="bool"/>
<preference id="accessibility.blockautorefresh" name="accessibility.blockautorefresh" type="bool"/>
<preference id="general.autoScroll" name="general.autoScroll" type="bool"/>
<preference id="general.smoothScroll" name="general.smoothScroll" type="bool"/>
@ -143,6 +144,10 @@
label="&searchStartTyping.label;"
accesskey="&searchStartTyping.accesskey;"
preference="accessibility.typeaheadfind"/>
<checkbox id="blockAutoRefresh"
label="&blockAutoRefresh.label;"
accesskey="&blockAutoRefresh.accesskey;"
preference="accessibility.blockautorefresh"/>
</groupbox>
<!-- Browsing -->

View File

@ -125,3 +125,9 @@ tabContext.undoCloseTabAccessKey=U
# History menu
menuOpenAllInTabs.label=Open All in Tabs
menuOpenAllInTabs.accesskey=o
# Block autorefresh
refreshBlocked.goButton=Allow
refreshBlocked.goButton.accesskey=A
refreshBlocked.refreshLabel=%S prevented this page from automatically reloading.
refreshBlocked.redirectLabel=%S prevented this page from automatically redirecting to another page.

View File

@ -9,6 +9,8 @@
<!ENTITY useCursorNavigation.accesskey "c">
<!ENTITY searchStartTyping.label "Search for text when I start typing">
<!ENTITY searchStartTyping.accesskey "x">
<!ENTITY blockAutoRefresh.label "Warn me when web sites try to redirect or reload the page">
<!ENTITY blockAutoRefresh.accesskey "r">
<!ENTITY browsing.label "Browsing">

View File

@ -222,6 +222,18 @@ nsDownloadListener::OnProgressChange64(nsIWebProgress *aWebProgress,
return NS_OK;
}
/* boolean onRefreshAttempted (in nsIWebProgress aWebProgress, in nsIURI aRefreshURI, in long aDelay, in boolean aSameURI); */
NS_IMETHODIMP
nsDownloadListener::OnRefreshAttempted(nsIWebProgress *aWebProgress,
nsIURI *aUri,
PRInt32 aDelay,
PRBool aSameUri,
PRBool *allowRefresh)
{
*allowRefresh = PR_TRUE;
return NS_OK;
}
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
NS_IMETHODIMP
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,

View File

@ -643,6 +643,18 @@ CHBrowserListener::OnProgressChange64(nsIWebProgress *aWebProgress, nsIRequest *
return NS_OK;
}
/* boolean onRefreshAttempted (in nsIWebProgress aWebProgress, in nsIURI aRefreshURI, in long aDelay, in boolean aSameURI); */
NS_IMETHODIMP
CHDownloadListener::OnRefreshAttempted(nsIWebProgress *aWebProgress,
nsIURI *aUri,
PRInt32 aDelay,
PRBool aSameUri,
PRBool *allowRefresh)
{
*allowRefresh = PR_TRUE;
return NS_OK;
}
//
// Implementation of nsIWebProgressListener
//

View File

@ -4112,10 +4112,31 @@ nsDocShell::GetScriptGlobalObject()
//*****************************************************************************
NS_IMETHODIMP
nsDocShell::RefreshURI(nsIURI * aURI, PRInt32 aDelay, PRBool aRepeat, PRBool aMetaRefresh)
nsDocShell::RefreshURI(nsIURI * aURI, PRInt32 aDelay, PRBool aRepeat,
PRBool aMetaRefresh)
{
NS_ENSURE_ARG(aURI);
/* Check if Meta refresh/redirects are permitted. Some
* embedded applications may not want to do this.
* Must do this before sending out NOTIFY_REFRESH events
* because listeners may have side effects (e.g. displaying a
* button to manually trigger the refresh later).
*/
PRBool allowRedirects = PR_TRUE;
GetAllowMetaRedirects(&allowRedirects);
if (!allowRedirects)
return NS_OK;
// If any web progress listeners are listening for NOTIFY_REFRESH events,
// give them a chance to block this refresh.
PRBool sameURI;
nsresult rv = aURI->Equals(mCurrentURI, &sameURI);
if (NS_FAILED(rv))
sameURI = PR_FALSE;
if (!RefreshAttempted(this, aURI, aDelay, sameURI))
return NS_OK;
nsRefreshTimer *refreshTimer = new nsRefreshTimer();
NS_ENSURE_TRUE(refreshTimer, NS_ERROR_OUT_OF_MEMORY);
PRUint32 busyFlags = 0;
@ -4152,6 +4173,66 @@ nsDocShell::RefreshURI(nsIURI * aURI, PRInt32 aDelay, PRBool aRepeat, PRBool aMe
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::ForceRefreshURI(nsIURI * aURI,
PRInt32 aDelay,
PRBool aMetaRefresh)
{
NS_ENSURE_ARG(aURI);
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
CreateLoadInfo(getter_AddRefs(loadInfo));
NS_ENSURE_TRUE(loadInfo, NS_ERROR_OUT_OF_MEMORY);
/* We do need to pass in a referrer, but we don't want it to
* be sent to the server.
*/
loadInfo->SetSendReferrer(PR_FALSE);
/* for most refreshes the current URI is an appropriate
* internal referrer
*/
loadInfo->SetReferrer(mCurrentURI);
/* Check if this META refresh causes a redirection
* to another site.
*/
PRBool equalUri = PR_FALSE;
nsresult rv = aURI->Equals(mCurrentURI, &equalUri);
if (NS_SUCCEEDED(rv) && (!equalUri) && aMetaRefresh) {
/* It is a META refresh based redirection. Now check if it happened
within the threshold time we have in mind(15000 ms as defined by
REFRESH_REDIRECT_TIMER). If so, pass a REPLACE flag to LoadURI().
*/
if (aDelay <= REFRESH_REDIRECT_TIMER) {
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadNormalReplace);
/* for redirects we mimic HTTP, which passes the
* original referrer
*/
nsCOMPtr<nsIURI> internalReferrer;
GetReferringURI(getter_AddRefs(internalReferrer));
if (internalReferrer) {
loadInfo->SetReferrer(internalReferrer);
}
}
else
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh);
/*
* LoadURI(...) will cancel all refresh timers... This causes the
* Timer and its refreshData instance to be released...
*/
LoadURI(aURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_TRUE);
return NS_OK;
}
else
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh);
LoadURI(aURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_TRUE);
return NS_OK;
}
nsresult
nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI,
@ -8596,77 +8677,12 @@ nsRefreshTimer::Notify(nsITimer * aTimer)
NS_ASSERTION(mDocShell, "DocShell is somehow null");
if (mDocShell && aTimer) {
/* Check if Meta refresh/redirects are permitted. Some
* embedded applications may not want to do this.
*/
PRBool allowRedirects = PR_TRUE;
mDocShell->GetAllowMetaRedirects(&allowRedirects);
if (!allowRedirects)
return NS_OK;
// Get the delay count
// Get the delay count to determine load type
PRUint32 delay = 0;
aTimer->GetDelay(&delay);
// Get the current uri from the docshell.
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
nsCOMPtr<nsIURI> currURI;
if (webNav) {
webNav->GetCurrentURI(getter_AddRefs(currURI));
}
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
mDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
NS_ENSURE_TRUE(loadInfo, NS_OK);
/* We do need to pass in a referrer, but we don't want it to
* be sent to the server.
*/
loadInfo->SetSendReferrer(PR_FALSE);
/* for most refreshes the current URI is an appropriate
* internal referrer
*/
loadInfo->SetReferrer(currURI);
/* Check if this META refresh causes a redirection
* to another site.
*/
PRBool equalUri = PR_FALSE;
nsresult rv = mURI->Equals(currURI, &equalUri);
if (NS_SUCCEEDED(rv) && (!equalUri) && mMetaRefresh) {
/* It is a META refresh based redirection. Now check if it happened within
* the threshold time we have in mind(15000 ms as defined by REFRESH_REDIRECT_TIMER).
* If so, pass a REPLACE flag to LoadURI().
*/
if (delay <= REFRESH_REDIRECT_TIMER) {
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadNormalReplace);
/* for redirects we mimic HTTP, which passes the
* original referrer
*/
nsCOMPtr<nsIURI> internalReferrer;
nsCOMPtr<nsIWebNavigation> webNav =
do_QueryInterface(mDocShell);
if (webNav) {
webNav->GetReferringURI(getter_AddRefs(internalReferrer));
if (internalReferrer) {
loadInfo->SetReferrer(internalReferrer);
}
}
}
else
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh);
/*
* LoadURL(...) will cancel all refresh timers... This causes the Timer and
* its refreshData instance to be released...
*/
mDocShell->LoadURI(mURI, loadInfo,
nsIWebNavigation::LOAD_FLAGS_NONE, PR_TRUE);
return NS_OK;
}
else
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh);
mDocShell->LoadURI(mURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_TRUE);
nsCOMPtr<nsIRefreshURI> refreshURI = do_QueryInterface(mDocShell);
if (refreshURI)
refreshURI->ForceRefreshURI(mURI, delay, mMetaRefresh);
}
return NS_OK;
}

View File

@ -219,7 +219,6 @@ nsDownloadListener::OnProgressChange64(nsIWebProgress *aWebProgress,
}
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
NS_IMETHODIMP
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
@ -268,6 +267,18 @@ nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRe
return NS_OK;
}
/* boolean onRefreshAttempted (in nsIWebProgress aWebProgress, in nsIURI aRefreshURI, in long aDelay, in boolean aSameURI); */
NS_IMETHODIMP
nsDownloadListener::OnRefreshAttempted(nsIWebProgress *aWebProgress,
nsIURI *aUri,
PRInt32 aDelay,
PRBool aSameUri,
PRBool *allowRefresh)
{
*allowRefresh = PR_TRUE;
return NS_OK;
}
#pragma mark -
void

View File

@ -159,3 +159,9 @@ NS_IMETHODIMP EmbedDownload::OnStatusChange(nsIWebProgress* aWebProgress, nsIReq
NS_IMETHODIMP EmbedDownload::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state) {
return NS_OK;
}
NS_IMETHODIMP EmbedDownload::OnRefreshAttempted(nsIWebProgress *aWebProgress, nsIURI *aUri, PRInt32 aDelay, PRBool aSameUri, PRBool *allowRefresh)
{
*allowRefresh = PR_TRUE;
return NS_OK;
}

View File

@ -226,6 +226,13 @@ NS_IMETHODIMP CDownload::OnSecurityChange(nsIWebProgress *aWebProgress, nsIReque
return NS_OK;
}
/* boolean onRefreshAttempted (in nsIWebProgress aWebProgress, in nsIURI aRefreshURI, in long aDelay, in boolean aSameURI); */
NS_IMETHODIMP CDownload::OnRefreshAttempted(nsIWebProgress *aWebProgress, nsIURI *aUri, PRInt32 aDelay, PRBool aSameUri, PRBool *allowRefresh)
{
*allowRefresh = PR_TRUE;
return NS_OK;
}
#pragma mark -
#pragma mark [CDownload Internal Methods]

View File

@ -224,7 +224,7 @@ nsHelperAppDialog.prototype = {
}
},
// Ignore onProgressChange, onStateChange, onLocationChange, and onSecurityChange notifications.
// Ignore onProgressChange, onProgressChange64, onStateChange, onLocationChange, onSecurityChange, and onRefreshAttempted notifications.
onProgressChange: function( aWebProgress,
aRequest,
aCurSelfProgress,
@ -248,6 +248,10 @@ nsHelperAppDialog.prototype = {
},
onSecurityChange: function( aWebProgress, aRequest, state ) {
},
onRefreshAttempted: function( aWebProgress, aURI, aDelay, aSameURI ) {
return true;
}
},

View File

@ -40,6 +40,7 @@ var reporterListener = {
QueryInterface: function(aIID) {
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
@ -67,7 +68,9 @@ var reporterListener = {
onProgressChange: function() { },
onStatusChange: function() { },
onSecurityChange: function() { },
onLinkIconAvailable: function() { }
onLinkIconAvailable: function() { },
onProgressChange64: function() { },
onRefreshAttempted: function() { return true; }
}
function onBrowserLoad() {

View File

@ -2068,6 +2068,17 @@ nsDownload::OnProgressChange64(nsIWebProgress *aWebProgress,
}
NS_IMETHODIMP
nsDownload::OnRefreshAttempted(nsIWebProgress *aWebProgress,
nsIURI *aUri,
PRInt32 aDelay,
PRBool aSameUri,
PRBool *allowRefresh)
{
*allowRefresh = PR_TRUE;
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////////
// nsIWebProgressListener

View File

@ -222,7 +222,15 @@ public:
return NS_OK;
}
NS_IMETHODIMP OnRefreshAttempted(nsIWebProgress *aWebProgress,
nsIURI *aUri,
PRInt32 aDelay,
PRBool aSameUri,
PRBool *allowRefresh)
{
*allowRefresh = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP OnSecurityChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest, PRUint32 aState)

View File

@ -29,6 +29,7 @@
- Seth Spitzer <sspitzer@mozilla.org>
- Simon Bünzli <zeniko@gmail.com>
- Michael Ventnor <ventnor.bugzilla@yahoo.com.au>
- Mark Pilgrim <pilgrim@gmail.com>
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
@ -286,6 +287,15 @@
this.mTotalProgress = aMaxTotalProgress ? aCurTotalProgress / aMaxTotalProgress : 0;
},
onProgressChange64 : function (aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress,
aCurTotalProgress, aMaxTotalProgress)
{
return this.onProgressChange(aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress,
aMaxTotalProgress);
},
onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
{
if (!aRequest)
@ -431,9 +441,23 @@
}
},
onRefreshAttempted : function(aWebProgress, aURI, aDelay, aSameURI)
{
var allowRefresh = true;
for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
var p = this.mTabBrowser.mProgressListeners[i];
if (p && "onRefreshAttempted" in p) {
if (!p.onRefreshAttempted(aWebProgress, aURI, aDelay, aSameURI))
allowRefresh = false;
}
}
return allowRefresh;
},
QueryInterface : function(aIID)
{
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;

View File

@ -357,7 +357,7 @@ nsUnknownContentTypeDialog.prototype = {
}
},
// Ignore onProgressChange, onStateChange, onLocationChange, and onSecurityChange notifications.
// Ignore onProgressChange, onProgressChange64, onStateChange, onLocationChange, onSecurityChange, and onRefreshAttempted notifications.
onProgressChange: function( aWebProgress,
aRequest,
aCurSelfProgress,
@ -383,7 +383,11 @@ nsUnknownContentTypeDialog.prototype = {
},
onSecurityChange: function( aWebProgress, aRequest, state ) {
}
},
onRefreshAttempted: function( aWebProgress, aURI, aDelay, aSameURI ) {
return true;
}
},
// initDialog: Fill various dialog fields with initial content.

View File

@ -42,6 +42,7 @@
#include "nsCURILoader.h"
#include "nsNetUtil.h"
#include "nsIHttpChannel.h"
#include "nsIWebProgressListener2.h"
#include "nsIServiceManager.h"
#include "nsXPIDLString.h"
@ -1327,6 +1328,66 @@ nsDocLoader::FireOnStatusChange(nsIWebProgress* aWebProgress,
}
}
PRBool
nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress,
nsIURI *aURI,
PRInt32 aDelay,
PRBool aSameURI)
{
/*
* Returns true if the refresh may proceed,
* false if the refresh should be blocked.
*
* First notify any listeners of the refresh attempt...
*
* Iterate the elements from back to front so that if items
* get removed from the list it won't affect our iteration
*/
PRBool allowRefresh = PR_TRUE;
PRInt32 count = mListenerInfoList.Count();
while (--count >= 0) {
nsListenerInfo *info;
info = NS_STATIC_CAST(nsListenerInfo*,mListenerInfoList.SafeElementAt(count));
if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) {
continue;
}
nsCOMPtr<nsIWebProgressListener> listener =
do_QueryReferent(info->mWeakListener);
if (!listener) {
// the listener went away. gracefully pull it out of the list.
mListenerInfoList.RemoveElementAt(count);
delete info;
continue;
}
nsCOMPtr<nsIWebProgressListener2> listener2 =
do_QueryReferent(info->mWeakListener);
if (!listener2)
continue;
PRBool listenerAllowedRefresh;
nsresult listenerRV = listener2->OnRefreshAttempted(
aWebProgress, aURI, aDelay, aSameURI, &listenerAllowedRefresh);
if (NS_FAILED(listenerRV))
continue;
allowRefresh = allowRefresh && listenerAllowedRefresh;
}
mListenerInfoList.Compact();
// Pass the notification up to the parent...
if (mParent) {
allowRefresh = allowRefresh &&
mParent->RefreshAttempted(aWebProgress, aURI, aDelay, aSameURI);
}
return allowRefresh;
}
nsListenerInfo *
nsDocLoader::GetListenerInfo(nsIWebProgressListener *aListener)
{

View File

@ -168,6 +168,11 @@ protected:
nsIRequest* aRequest,
nsIURI *aUri);
PRBool RefreshAttempted(nsIWebProgress* aWebProgress,
nsIURI *aURI,
PRInt32 aDelay,
PRBool aSameURI);
// this function is overridden by the docshell, it is provided so that we
// can pass more information about redirect state (the normal OnStateChange
// doesn't get the new channel).

View File

@ -23,6 +23,7 @@
* Contributor(s):
* Travis Bogard <travis@netscape.com>
* Darin Fisher <darin@meer.net>
* Mark Pilgrim <pilgrim@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -115,16 +116,21 @@ interface nsIWebProgress : nsISupports
*
* NOTIFY_LOCATION
* Receive onLocationChange events.
*
* NOTIFY_REFRESH
* Receive onRefreshAttempted events.
* This is defined on nsIWebProgressListener2.
*/
const unsigned long NOTIFY_PROGRESS = 0x00000010;
const unsigned long NOTIFY_STATUS = 0x00000020;
const unsigned long NOTIFY_SECURITY = 0x00000040;
const unsigned long NOTIFY_LOCATION = 0x00000080;
const unsigned long NOTIFY_REFRESH = 0x00000100;
/**
* This flag enables all notifications.
*/
const unsigned long NOTIFY_ALL = 0x000000ff;
const unsigned long NOTIFY_ALL = 0x000001ff;
/**
* Registers a listener to receive web progress events.

View File

@ -19,6 +19,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark Pilgrim <pilgrim@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -37,10 +38,9 @@
#include "nsIWebProgressListener.idl"
/**
* This interface is an extension to nsIWebProgressListener to support 64-bit
* progress values.
* An extended version of nsIWebProgressListener.
*/
[scriptable, uuid(3f24610d-1e1f-4151-9d2e-239884742324)]
[scriptable, uuid(dde39de0-e4e0-11da-8ad9-0800200c9a66)]
interface nsIWebProgressListener2 : nsIWebProgressListener {
/**
* Notification that the progress has changed for one of the requests
@ -75,5 +75,28 @@ interface nsIWebProgressListener2 : nsIWebProgressListener {
in long long aMaxSelfProgress,
in long long aCurTotalProgress,
in long long aMaxTotalProgress);
};
/**
* Notification that a refresh or redirect has been requested in aWebProgress
* For example, via a <meta http-equiv="refresh"> or an HTTP Refresh: header
*
* @param aWebProgress
* The nsIWebProgress instance that fired the notification.
* @param aRefreshURI
* The new URI that aWebProgress has requested redirecting to.
* @param aMillis
* The delay (in milliseconds) before refresh.
* @param aSameURI
* True if aWebProgress is requesting a refresh of the
* current URI.
* False if aWebProgress is requesting a redirection to
* a different URI.
*
* @return True if the refresh may proceed.
* False if the refresh should be aborted.
*/
boolean onRefreshAttempted(in nsIWebProgress aWebProgress,
in nsIURI aRefreshURI,
in long aMillis,
in boolean aSameURI);
};

View File

@ -21,6 +21,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark Pilgrim <pilgrim@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -40,7 +41,7 @@
#include "nsIURI.idl"
interface nsIChannel;
[scriptable, uuid(69EFC430-2EFE-11d2-9E5D-006008BF092E)]
[scriptable, uuid(c25b6df0-e4e0-11da-8ad9-0800200c9a66)]
interface nsIRefreshURI : nsISupports {
/**
* Load a uri after waiting for aMillis milliseconds. If the docshell
@ -51,9 +52,20 @@ interface nsIRefreshURI : nsISupports {
* @param aMillis The number of milliseconds to wait.
* @param aRepeat Flag to indicate if the uri is to be
* repeatedly refreshed every aMillis milliseconds.
* @parem aMetaRefresh Flag to indicate if this is a Meta refresh.
* @param aMetaRefresh Flag to indicate if this is a Meta refresh.
*/
void refreshURI(in nsIURI aURI, in long aMillis, in boolean aRepeat, in boolean aMetaRefresh);
void refreshURI(in nsIURI aURI, in long aMillis, in boolean aRepeat,
in boolean aMetaRefresh);
/**
* Loads a URI immediately as if it were a refresh.
*
* @param aURI The URI to refresh.
* @param aMillis The number of milliseconds by which this refresh would
* be delayed if it were not being forced.
* @param aMetaRefresh Flag to indicate if this is a meta refresh.
*/
void forceRefreshURI(in nsIURI aURI, in long aMillis, in boolean aMetaRefresh);
/**
* Checks the passed in channel to see if there is a refresh header,

View File

@ -69,9 +69,10 @@ nsBrowserStatusFilter::~nsBrowserStatusFilter()
// nsBrowserStatusFilter::nsISupports
//-----------------------------------------------------------------------------
NS_IMPL_ISUPPORTS3(nsBrowserStatusFilter,
NS_IMPL_ISUPPORTS4(nsBrowserStatusFilter,
nsIWebProgress,
nsIWebProgressListener,
nsIWebProgressListener2,
nsISupportsWeakReference)
//-----------------------------------------------------------------------------
@ -199,14 +200,16 @@ nsBrowserStatusFilter::OnProgressChange(nsIWebProgress *aWebProgress,
// limit frequency of calls to OnProgressChange
//
mCurProgress = aCurTotalProgress;
mMaxProgress = aMaxTotalProgress;
mCurProgress = (PRInt64)aCurTotalProgress;
mMaxProgress = (PRInt64)aMaxTotalProgress;
if (mDelayedProgress)
return NS_OK;
if (!mDelayedStatus) {
mListener->OnProgressChange(nsnull, nsnull, 0, 0, mCurProgress, mMaxProgress);
mListener->OnProgressChange(nsnull, nsnull, 0, 0,
(PRInt32)mCurProgress,
(PRInt32)mMaxProgress);
StartDelayTimer();
}
@ -265,6 +268,41 @@ nsBrowserStatusFilter::OnSecurityChange(nsIWebProgress *aWebProgress,
return mListener->OnSecurityChange(aWebProgress, aRequest, aState);
}
//-----------------------------------------------------------------------------
// nsBrowserStatusFilter::nsIWebProgressListener2
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsBrowserStatusFilter::OnProgressChange64(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRInt64 aCurSelfProgress,
PRInt64 aMaxSelfProgress,
PRInt64 aCurTotalProgress,
PRInt64 aMaxTotalProgress)
{
// XXX truncates 64-bit to 32-bit
return OnProgressChange(aWebProgress, aRequest,
(PRInt32)aCurSelfProgress,
(PRInt32)aMaxSelfProgress,
(PRInt32)aCurTotalProgress,
(PRInt32)aMaxTotalProgress);
}
NS_IMETHODIMP
nsBrowserStatusFilter::OnRefreshAttempted(nsIWebProgress *aWebProgress,
nsIURI *aUri,
PRInt32 aDelay,
PRBool aSameUri,
PRBool *allowRefresh)
{
nsCOMPtr<nsIWebProgressListener2> listener =
do_QueryInterface(mListener);
if (!listener)
return NS_OK;
return listener->OnRefreshAttempted(aWebProgress, aUri, aDelay, aSameUri,
allowRefresh);
}
//-----------------------------------------------------------------------------
// nsBrowserStatusFilter <private>
//-----------------------------------------------------------------------------
@ -297,7 +335,10 @@ nsBrowserStatusFilter::ProcessTimeout()
if (mDelayedProgress) {
mDelayedProgress = PR_FALSE;
mListener->OnProgressChange(nsnull, nsnull, 0, 0, mCurProgress, mMaxProgress);
// XXX truncates 64-bit to 32-bit
mListener->OnProgressChange(nsnull, nsnull, 0, 0,
(PRInt32)mCurProgress,
(PRInt32)mMaxProgress);
}
}

View File

@ -39,6 +39,7 @@
#define nsBrowserStatusFilter_h__
#include "nsIWebProgressListener.h"
#include "nsIWebProgressListener2.h"
#include "nsIWebProgress.h"
#include "nsWeakReference.h"
#include "nsITimer.h"
@ -52,7 +53,7 @@
//-----------------------------------------------------------------------------
class nsBrowserStatusFilter : public nsIWebProgress
, public nsIWebProgressListener
, public nsIWebProgressListener2
, public nsSupportsWeakReference
{
public:
@ -62,6 +63,7 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBPROGRESS
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIWEBPROGRESSLISTENER2
private:
nsresult StartDelayTimer();
@ -76,8 +78,8 @@ private:
// delayed values
nsString mStatusMsg;
PRInt32 mCurProgress;
PRInt32 mMaxProgress;
PRInt64 mCurProgress;
PRInt64 mMaxProgress;
// used to convert OnStart/OnStop notifications into progress notifications
PRInt32 mTotalRequests;

View File

@ -1114,6 +1114,16 @@ nsDownload::OnProgressChange(nsIWebProgress *aWebProgress,
aCurTotalProgress, aMaxTotalProgress);
}
NS_IMETHODIMP
nsDownload::OnRefreshAttempted(nsIWebProgress *aWebProgress,
nsIURI *aUri,
PRInt32 aDelay,
PRBool aSameUri,
PRBool *allowRefresh)
{
*allowRefresh = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsDownload::OnLocationChange(nsIWebProgress *aWebProgress,