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
Родитель 6b85797166
Коммит d9df0f2a4f
26 изменённых файлов: 461 добавлений и 424 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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 -->

Просмотреть файл

@ -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.

Просмотреть файл

@ -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">

Просмотреть файл

@ -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,

Просмотреть файл

@ -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
//

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -1,327 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Conrad Carlen <ccarlen@netscape.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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "UDownload.h"
#include "nsIExternalHelperAppService.h"
#include "nsILocalFIleMac.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsIRequest.h"
#include "netCore.h"
#include "UDownloadDisplay.h"
#include "UMacUnicode.h"
#include "UNavServicesDialogs.h"
//*****************************************************************************
// CDownload
//*****************************************************************************
#pragma mark [CDownload]
ADownloadProgressView *CDownload::sProgressView;
CDownload::CDownload() :
mGotFirstStateChange(false), mIsNetworkTransfer(false),
mUserCanceled(false),
mStatus(NS_OK)
{
}
CDownload::~CDownload()
{
}
NS_IMPL_ISUPPORTS4(CDownload, nsIDownload, nsITransfer,
nsIWebProgressListener, nsIWebProgressListener2)
#pragma mark -
#pragma mark [CDownload::nsIDownload]
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in nsIMIMEInfo aMIMEInfo, in long long startTime, in nsILocalFile aTempFile, in nsICancelable aCancelable); */
NS_IMETHODIMP CDownload::Init(nsIURI *aSource, nsILocalFile *aTarget,
const PRUnichar *aDisplayName, nsIMIMEInfo *aMIMEInfo, PRInt64 startTime,
nsILocalFile* aTempFile, nsICancelable* aCancelable)
{
try {
mSource = aSource;
mDestination = aTarget;
mStartTime = startTime;
mPercentComplete = 0;
// We have to break this circular ref when the download is done
mCancelable = aCancelable;
EnsureProgressView();
sProgressView->AddDownloadItem(this);
}
catch (...) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
/* readonly attribute nsIURI source; */
NS_IMETHODIMP CDownload::GetSource(nsIURI * *aSource)
{
NS_ENSURE_ARG_POINTER(aSource);
NS_IF_ADDREF(*aSource = mSource);
return NS_OK;
}
/* readonly attribute nsILocalFile target; */
NS_IMETHODIMP CDownload::GetTarget(nsILocalFile * *aTarget)
{
NS_ENSURE_ARG_POINTER(aTarget);
NS_IF_ADDREF(*aTarget = mDestination);
return NS_OK;
}
/* readonly attribute nsICancelable cancelable; */
NS_IMETHODIMP CDownload::GetCancelable(nsIWebBrowserCancelable * *aCancelable)
{
NS_ENSURE_ARG_POINTER(aCancelable);
NS_IF_ADDREF(*aCancelable = mCancelable);
return NS_OK;
}
/* readonly attribute PRInt32 percentComplete; */
NS_IMETHODIMP CDownload::GetPercentComplete(PRInt32 *aPercentComplete)
{
NS_ENSURE_ARG_POINTER(aPercentComplete);
*aPercentComplete = mPercentComplete;
return NS_OK;
}
/* attribute wstring displayName; */
NS_IMETHODIMP CDownload::GetDisplayName(PRUnichar * *aDisplayName)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute long long startTime; */
NS_IMETHODIMP CDownload::GetStartTime(PRInt64 *aStartTime)
{
NS_ENSURE_ARG_POINTER(aStartTime);
*aStartTime = mStartTime;
return NS_OK;
}
/* readonly attribute double speed; */
NS_IMETHODIMP CDownload::GetSpeed(double *aSpeed)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute nsIMIMEInfo MIMEInfo; */
NS_IMETHODIMP CDownload::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
#pragma mark -
#pragma mark [CDownload::nsIWebProgressListener]
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */
NS_IMETHODIMP CDownload::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
{
// For a file download via the external helper app service, we will never get a start
// notification. The helper app service has gotten that notification before it created us.
if (!mGotFirstStateChange) {
mIsNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
mGotFirstStateChange = PR_TRUE;
BroadcastMessage(msg_OnDLStart, this);
}
if (NS_FAILED(aStatus) && NS_SUCCEEDED(mStatus))
mStatus = aStatus;
// We will get this even in the event of a cancel,
if ((aStateFlags & STATE_STOP) && (!mIsNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
mCancelable = nsnull;
BroadcastMessage(msg_OnDLComplete, this);
}
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 CDownload::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
{
if (mUserCanceled) {
mCancelable->Cancel(NS_BINDING_ABORTED);
mUserCanceled = false;
}
if (aMaxTotalProgress == -1)
mPercentComplete = -1;
else
mPercentComplete = (PRInt32)(((float)aCurTotalProgress / (float)aMaxTotalProgress) * 100.0 + 0.5);
MsgOnDLProgressChangeInfo info(this, aCurTotalProgress, aMaxTotalProgress);
BroadcastMessage(msg_OnDLProgressChange, &info);
return NS_OK;
}
/* void onProgressChange64 (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long long aCurSelfProgress, in long long aMaxSelfProgress, in long long aCurTotalProgress, in long long aMaxTotalProgress); */
NS_IMETHODIMP CDownload::OnProgressChange64(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt64 aCurSelfProgress, PRInt64 aMaxSelfProgress, PRInt64 aCurTotalProgress, PRInt64 aMaxTotalProgress)
{
// XXX truncates 64-bit to 32-bit
return OnProgressChange(aProgress, aRequest,
PRInt32(curSelfProgress), PRInt32(maxSelfProgress),
PRInt32(curTotalProgress), PRInt32(maxTotalProgress));
}
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
NS_IMETHODIMP CDownload::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location)
{
return NS_OK;
}
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
NS_IMETHODIMP CDownload::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
{
return NS_OK;
}
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
NS_IMETHODIMP CDownload::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
{
return NS_OK;
}
#pragma mark -
#pragma mark [CDownload Internal Methods]
void CDownload::Cancel()
{
mUserCanceled = true;
// nsWebBrowserPersist does the right thing: After canceling, next time through
// OnStateChange(), aStatus != NS_OK. This isn't the case with nsExternalHelperAppService.
mStatus = NS_ERROR_ABORT;
}
void CDownload::CreateProgressView()
{
sProgressView = new CMultiDownloadProgress;
ThrowIfNil_(sProgressView);
}
//*****************************************************************************
// CHelperAppLauncherDialog
//*****************************************************************************
#pragma mark -
#pragma mark [CHelperAppLauncherDialog]
CHelperAppLauncherDialog::CHelperAppLauncherDialog()
{
}
CHelperAppLauncherDialog::~CHelperAppLauncherDialog()
{
}
NS_IMPL_ISUPPORTS1(CHelperAppLauncherDialog, nsIHelperAppLauncherDialog)
/* void show (in nsIHelperAppLauncher aLauncher, in nsISupports aContext, in unsigned long aReason); */
NS_IMETHODIMP CHelperAppLauncherDialog::Show(nsIHelperAppLauncher *aLauncher, nsISupports *aContext, PRUint32 aReason)
{
return aLauncher->SaveToDisk(nsnull, PR_FALSE);
}
/* nsILocalFile promptForSaveToFile (in nsIHelperAppLauncher aLauncher, in nsISupports aWindowContext, in wstring aDefaultFile, in wstring aSuggestedFileExtension); */
NS_IMETHODIMP CHelperAppLauncherDialog::PromptForSaveToFile(nsIHelperAppLauncher* aLauncher,
nsISupports *aWindowContext,
const PRUnichar *aDefaultFile,
const PRUnichar *aSuggestedFileExtension,
nsILocalFile **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = nsnull;
static bool sFirstTime = true;
UNavServicesDialogs::LFileDesignator designator;
if (sFirstTime) {
// Get the default download folder and point Nav Sevices to it.
nsCOMPtr<nsIFile> defaultDownloadDir;
NS_GetSpecialDirectory(NS_MAC_DEFAULT_DOWNLOAD_DIR, getter_AddRefs(defaultDownloadDir));
if (defaultDownloadDir) {
nsCOMPtr<nsILocalFileMac> macDir(do_QueryInterface(defaultDownloadDir));
FSSpec defaultDownloadSpec;
if (NS_SUCCEEDED(macDir->GetFSSpec(&defaultDownloadSpec)))
designator.SetDefaultLocation(defaultDownloadSpec, true);
}
sFirstTime = false;
}
Str255 defaultName;
CPlatformUCSConversion::GetInstance()->UCSToPlatform(nsDependentString(aDefaultFile), defaultName);
bool result = designator.AskDesignateFile(defaultName);
// After the dialog is dismissed, process all activation an update events right away.
// The save dialog code calls UDesktop::Activate after dismissing the dialog. All that
// does is activate the now frontmost LWindow which was behind the dialog. It does not
// remove the activate event from the queue. If that event is not processed and removed
// before we show the progress window, bad things happen. Specifically, the progress
// dialog will show in front and then, shortly thereafter, the window which was behind this save
// dialog will be moved to the front.
if (LEventDispatcher::GetCurrentEventDispatcher()) { // Can this ever be NULL?
EventRecord theEvent;
while (::WaitNextEvent(updateMask | activMask, &theEvent, 0, nil))
LEventDispatcher::GetCurrentEventDispatcher()->DispatchEvent(theEvent);
}
if (result) {
FSSpec destSpec;
designator.GetFileSpec(destSpec);
nsCOMPtr<nsILocalFileMac> destFile;
NS_NewLocalFileWithFSSpec(&destSpec, PR_TRUE, getter_AddRefs(destFile));
if (!destFile)
return NS_ERROR_FAILURE;
*_retval = destFile;
NS_ADDREF(*_retval);
return NS_OK;
}
else
return NS_ERROR_ABORT;
}

Просмотреть файл

@ -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;
}
},

Просмотреть файл

@ -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() {

Просмотреть файл

@ -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

Просмотреть файл

@ -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)

Просмотреть файл

@ -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;

Просмотреть файл

@ -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.

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -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).

Просмотреть файл

@ -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.

Просмотреть файл

@ -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);
};

Просмотреть файл

@ -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,

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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,