From ebcefa5a9818bda6a2813555c350d032de871917 Mon Sep 17 00:00:00 2001 From: "mozilla.mano%sent.com" Date: Thu, 8 Feb 2007 13:15:50 +0000 Subject: [PATCH] Bug 83265 - Add a way to disable HTTP-EQUIV=refresh. patch from Mark Pilgrim , r=biesi,mano,mento. sr=bz. git-svn-id: svn://10.0.0.236/trunk@219699 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/browser/app/profile/firefox.js | 3 + mozilla/browser/base/content/browser.js | 77 ++++++++- .../browser/base/content/utilityOverlay.js | 10 ++ .../components/preferences/advanced.xul | 5 + .../en-US/chrome/browser/browser.properties | 6 + .../chrome/browser/preferences/advanced.dtd | 2 + .../camino/src/download/nsDownloadListener.mm | 12 ++ .../camino/src/embedding/CHBrowserListener.mm | 12 ++ mozilla/docshell/base/nsDocShell.cpp | 156 ++++++++++-------- .../browser/cocoa/src/nsDownloadListener.mm | 13 +- .../browser/photon/src/EmbedDownload.cpp | 6 + .../browser/powerplant/source/UDownload.cpp | 7 + .../ui/helperAppDlg/nsHelperAppDlg.js | 6 +- .../content/reporter/reporterOverlay.js | 5 +- .../downloads/src/nsDownloadManager.cpp | 11 ++ .../downloads/src/nsDownloadProxy.h | 10 +- .../toolkit/content/widgets/tabbrowser.xml | 24 +++ .../downloads/src/nsHelperAppDlg.js.in | 8 +- mozilla/uriloader/base/nsDocLoader.cpp | 61 +++++++ mozilla/uriloader/base/nsDocLoader.h | 5 + mozilla/uriloader/base/nsIWebProgress.idl | 8 +- .../base/nsIWebProgressListener2.idl | 31 +++- mozilla/webshell/public/nsIRefreshURI.idl | 18 +- .../browser/src/nsBrowserStatusFilter.cpp | 51 +++++- .../xpfe/browser/src/nsBrowserStatusFilter.h | 8 +- .../src/nsDownloadManager.cpp | 10 ++ 26 files changed, 468 insertions(+), 97 deletions(-) diff --git a/mozilla/browser/app/profile/firefox.js b/mozilla/browser/app/profile/firefox.js index 1c10235050a..48604cf5f81 100644 --- a/mozilla/browser/app/profile/firefox.js +++ b/mozilla/browser/app/profile/firefox.js @@ -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); diff --git a/mozilla/browser/base/content/browser.js b/mozilla/browser/base/content/browser.js index 5fe479ac740..147829ad1df 100644 --- a/mozilla/browser/base/content/browser.js +++ b/mozilla/browser/base/content/browser.js @@ -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; diff --git a/mozilla/browser/base/content/utilityOverlay.js b/mozilla/browser/base/content/utilityOverlay.js index cc460bc5b1d..33258f13f40 100644 --- a/mozilla/browser/base/content/utilityOverlay.js +++ b/mozilla/browser/base/content/utilityOverlay.js @@ -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; +} diff --git a/mozilla/browser/components/preferences/advanced.xul b/mozilla/browser/components/preferences/advanced.xul index ef22860ae7c..5604dbded95 100644 --- a/mozilla/browser/components/preferences/advanced.xul +++ b/mozilla/browser/components/preferences/advanced.xul @@ -67,6 +67,7 @@ + @@ -143,6 +144,10 @@ label="&searchStartTyping.label;" accesskey="&searchStartTyping.accesskey;" preference="accessibility.typeaheadfind"/> + diff --git a/mozilla/browser/locales/en-US/chrome/browser/browser.properties b/mozilla/browser/locales/en-US/chrome/browser/browser.properties index b14ecc43fb6..0a7e34f6022 100644 --- a/mozilla/browser/locales/en-US/chrome/browser/browser.properties +++ b/mozilla/browser/locales/en-US/chrome/browser/browser.properties @@ -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. diff --git a/mozilla/browser/locales/en-US/chrome/browser/preferences/advanced.dtd b/mozilla/browser/locales/en-US/chrome/browser/preferences/advanced.dtd index 1cbad5d0ae2..cec1aec793a 100644 --- a/mozilla/browser/locales/en-US/chrome/browser/preferences/advanced.dtd +++ b/mozilla/browser/locales/en-US/chrome/browser/preferences/advanced.dtd @@ -9,6 +9,8 @@ + + diff --git a/mozilla/camino/src/download/nsDownloadListener.mm b/mozilla/camino/src/download/nsDownloadListener.mm index e762f3298f7..4cf8716f998 100644 --- a/mozilla/camino/src/download/nsDownloadListener.mm +++ b/mozilla/camino/src/download/nsDownloadListener.mm @@ -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, diff --git a/mozilla/camino/src/embedding/CHBrowserListener.mm b/mozilla/camino/src/embedding/CHBrowserListener.mm index 8043c0db160..dacbf6ca8b6 100644 --- a/mozilla/camino/src/embedding/CHBrowserListener.mm +++ b/mozilla/camino/src/embedding/CHBrowserListener.mm @@ -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 // diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index be48cd2849e..8a783bfeee9 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -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 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 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 webNav(do_QueryInterface(mDocShell)); - nsCOMPtr currURI; - if (webNav) { - webNav->GetCurrentURI(getter_AddRefs(currURI)); - } - nsCOMPtr 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 internalReferrer; - nsCOMPtr 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 refreshURI = do_QueryInterface(mDocShell); + if (refreshURI) + refreshURI->ForceRefreshURI(mURI, delay, mMetaRefresh); } return NS_OK; } diff --git a/mozilla/embedding/browser/cocoa/src/nsDownloadListener.mm b/mozilla/embedding/browser/cocoa/src/nsDownloadListener.mm index 54abd8cbcab..e1ee898f718 100644 --- a/mozilla/embedding/browser/cocoa/src/nsDownloadListener.mm +++ b/mozilla/embedding/browser/cocoa/src/nsDownloadListener.mm @@ -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 diff --git a/mozilla/embedding/browser/photon/src/EmbedDownload.cpp b/mozilla/embedding/browser/photon/src/EmbedDownload.cpp index 03363498652..77c83daebfc 100644 --- a/mozilla/embedding/browser/photon/src/EmbedDownload.cpp +++ b/mozilla/embedding/browser/photon/src/EmbedDownload.cpp @@ -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; +} + diff --git a/mozilla/embedding/browser/powerplant/source/UDownload.cpp b/mozilla/embedding/browser/powerplant/source/UDownload.cpp index 53040691db5..10ffc06b832 100644 --- a/mozilla/embedding/browser/powerplant/source/UDownload.cpp +++ b/mozilla/embedding/browser/powerplant/source/UDownload.cpp @@ -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] diff --git a/mozilla/embedding/components/ui/helperAppDlg/nsHelperAppDlg.js b/mozilla/embedding/components/ui/helperAppDlg/nsHelperAppDlg.js index 1246c21a507..e050af6a6cc 100644 --- a/mozilla/embedding/components/ui/helperAppDlg/nsHelperAppDlg.js +++ b/mozilla/embedding/components/ui/helperAppDlg/nsHelperAppDlg.js @@ -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; } }, diff --git a/mozilla/extensions/reporter/resources/content/reporter/reporterOverlay.js b/mozilla/extensions/reporter/resources/content/reporter/reporterOverlay.js index be042fb72c9..347bad08923 100644 --- a/mozilla/extensions/reporter/resources/content/reporter/reporterOverlay.js +++ b/mozilla/extensions/reporter/resources/content/reporter/reporterOverlay.js @@ -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() { diff --git a/mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp b/mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp index a3ab066bb8d..c4368af5f6d 100644 --- a/mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp +++ b/mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp @@ -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 diff --git a/mozilla/toolkit/components/downloads/src/nsDownloadProxy.h b/mozilla/toolkit/components/downloads/src/nsDownloadProxy.h index 6d3228d0aac..16a32d5d777 100644 --- a/mozilla/toolkit/components/downloads/src/nsDownloadProxy.h +++ b/mozilla/toolkit/components/downloads/src/nsDownloadProxy.h @@ -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) diff --git a/mozilla/toolkit/content/widgets/tabbrowser.xml b/mozilla/toolkit/content/widgets/tabbrowser.xml index 3dfc05db207..63e11dac284 100644 --- a/mozilla/toolkit/content/widgets/tabbrowser.xml +++ b/mozilla/toolkit/content/widgets/tabbrowser.xml @@ -29,6 +29,7 @@ - Seth Spitzer - Simon Bünzli - Michael Ventnor + - Mark Pilgrim - - 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; diff --git a/mozilla/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in b/mozilla/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in index 964ca1cad9b..3a6d2c61ce4 100644 --- a/mozilla/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in +++ b/mozilla/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in @@ -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. diff --git a/mozilla/uriloader/base/nsDocLoader.cpp b/mozilla/uriloader/base/nsDocLoader.cpp index 1adf5ee407f..b419d27491a 100644 --- a/mozilla/uriloader/base/nsDocLoader.cpp +++ b/mozilla/uriloader/base/nsDocLoader.cpp @@ -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 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 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) { diff --git a/mozilla/uriloader/base/nsDocLoader.h b/mozilla/uriloader/base/nsDocLoader.h index 49ac09b6539..acbb6f852d9 100644 --- a/mozilla/uriloader/base/nsDocLoader.h +++ b/mozilla/uriloader/base/nsDocLoader.h @@ -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). diff --git a/mozilla/uriloader/base/nsIWebProgress.idl b/mozilla/uriloader/base/nsIWebProgress.idl index de39ac32966..8bad286f1d5 100644 --- a/mozilla/uriloader/base/nsIWebProgress.idl +++ b/mozilla/uriloader/base/nsIWebProgress.idl @@ -23,6 +23,7 @@ * Contributor(s): * Travis Bogard * Darin Fisher + * Mark Pilgrim * * 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. diff --git a/mozilla/uriloader/base/nsIWebProgressListener2.idl b/mozilla/uriloader/base/nsIWebProgressListener2.idl index 58d9df2b705..20afd868ad5 100644 --- a/mozilla/uriloader/base/nsIWebProgressListener2.idl +++ b/mozilla/uriloader/base/nsIWebProgressListener2.idl @@ -19,6 +19,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Mark Pilgrim * * 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 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); +}; diff --git a/mozilla/webshell/public/nsIRefreshURI.idl b/mozilla/webshell/public/nsIRefreshURI.idl index c00a5298ddd..f8544c60b0d 100644 --- a/mozilla/webshell/public/nsIRefreshURI.idl +++ b/mozilla/webshell/public/nsIRefreshURI.idl @@ -21,6 +21,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Mark Pilgrim * * 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, diff --git a/mozilla/xpfe/browser/src/nsBrowserStatusFilter.cpp b/mozilla/xpfe/browser/src/nsBrowserStatusFilter.cpp index e54fbf6250c..5a6f6580e9a 100644 --- a/mozilla/xpfe/browser/src/nsBrowserStatusFilter.cpp +++ b/mozilla/xpfe/browser/src/nsBrowserStatusFilter.cpp @@ -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 listener = + do_QueryInterface(mListener); + if (!listener) + return NS_OK; + + return listener->OnRefreshAttempted(aWebProgress, aUri, aDelay, aSameUri, + allowRefresh); +} + //----------------------------------------------------------------------------- // nsBrowserStatusFilter //----------------------------------------------------------------------------- @@ -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); } } diff --git a/mozilla/xpfe/browser/src/nsBrowserStatusFilter.h b/mozilla/xpfe/browser/src/nsBrowserStatusFilter.h index b86987285db..27907f9146b 100644 --- a/mozilla/xpfe/browser/src/nsBrowserStatusFilter.h +++ b/mozilla/xpfe/browser/src/nsBrowserStatusFilter.h @@ -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; diff --git a/mozilla/xpfe/components/download-manager/src/nsDownloadManager.cpp b/mozilla/xpfe/components/download-manager/src/nsDownloadManager.cpp index 6b42423e9d5..9ab2bf3d42d 100644 --- a/mozilla/xpfe/components/download-manager/src/nsDownloadManager.cpp +++ b/mozilla/xpfe/components/download-manager/src/nsDownloadManager.cpp @@ -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,