diff --git a/mozilla/docshell/base/nsWebShell.cpp b/mozilla/docshell/base/nsWebShell.cpp index 332f3c37275..57e1ec53dcc 100644 --- a/mozilla/docshell/base/nsWebShell.cpp +++ b/mozilla/docshell/base/nsWebShell.cpp @@ -41,6 +41,8 @@ #include "nsPluginsCID.h" #include "nsIPref.h" #include "nsIBrowserWindow.h" +#include "nsIRefreshUrl.h" +#include "nsITimer.h" #include "prlog.h" @@ -91,7 +93,8 @@ class nsWebShell : public nsIWebShell, public nsIWebShellContainer, public nsILinkHandler, public nsIScriptContextOwner, - public nsIDocumentLoaderObserver + public nsIDocumentLoaderObserver, + public nsIRefreshUrl { public: nsWebShell(); @@ -193,6 +196,11 @@ public: // nsIDocumentLoaderObserver NS_IMETHOD OnConnectionsComplete(); + // nsIRefreshURL interface methods... + NS_IMETHOD RefreshURL(nsIURL* aURL, PRInt32 millis, PRBool repeat); + NS_IMETHOD CancelRefreshURLTimers(void); + + // nsWebShell void HandleLinkClickEvent(const PRUnichar* aURLSpec, const PRUnichar* aTargetSpec, @@ -202,6 +210,8 @@ public: nsIWebShell* GetTarget(const PRUnichar* aName); + static void RefreshURLCallback(nsITimer* aTimer, void* aClosure); + static nsEventStatus PR_CALLBACK HandleEvent(nsGUIEvent *aEvent); static nsresult CreatePluginHost(void); @@ -234,6 +244,7 @@ protected: nsScrollPreference mScrollPref; PRInt32 mMarginWidth; PRInt32 mMarginHeight; + nsVoidArray mRefreshments; void ReleaseChildren(); @@ -267,6 +278,7 @@ static NS_DEFINE_IID(kCPluginHostCID, NS_PLUGIN_HOST_CID); static NS_DEFINE_IID(kIBrowserWindowIID, NS_IBROWSER_WINDOW_IID); static NS_DEFINE_IID(kIDocumentLoaderObserverIID, NS_IDOCUMENT_LOADER_OBSERVER_IID); static NS_DEFINE_IID(kIDocumentViewerIID, NS_IDOCUMENT_VIEWER_IID); +static NS_DEFINE_IID(kRefreshURLIID, NS_IREFRESHURL_IID); // XXX not sure static NS_DEFINE_IID(kILinkHandlerIID, NS_ILINKHANDLER_IID); @@ -317,11 +329,11 @@ nsWebShell::~nsWebShell() // Stop any pending document loads and destroy the loader... if (nsnull != mDocLoader) { mDocLoader->Stop(); - // Cancel any timers that were set for this loader. - mDocLoader->CancelLoadURLTimer(); mDocLoader->RemoveObserver((nsIDocumentLoaderObserver*)this); NS_RELEASE(mDocLoader); } + // Cancel any timers that were set for this loader. + CancelRefreshURLTimers(); NS_IF_RELEASE(mInnerWindow); @@ -398,6 +410,11 @@ nsWebShell::QueryInterface(REFNSIID aIID, void** aInstancePtr) AddRef(); return NS_OK; } + if (aIID.Equals(kRefreshURLIID)) { + *aInstancePtr = (void*)(nsIRefreshUrl*)this; + AddRef(); + return NS_OK; + } if (nsnull != mInnerWindow) { return mInnerWindow->QueryInterface(aIID, aInstancePtr); } @@ -560,7 +577,7 @@ nsWebShell::Destroy() mDocLoader->Stop(); // Cancel any timers that were set for this loader. - mDocLoader->CancelLoadURLTimer(); + CancelRefreshURLTimers(); SetContainer(nsnull); SetObserver(nsnull); @@ -991,12 +1008,17 @@ nsWebShell::LoadURL(const PRUnichar *aURLSpec, Stop(); + // Cancel any timers that were set for this loader. + CancelRefreshURLTimers(); + rv = mDocLoader->LoadURL(urlSpec, // URL string nsnull, // Command this, // Container aPostData, // Post Data nsnull, // Extra Info... - mObserver); // Observer + mObserver); // Observer + + return rv; } @@ -1007,7 +1029,7 @@ NS_IMETHODIMP nsWebShell::Stop(void) mDocLoader->Stop(); // Cancel any timers that were set for this loader. - mDocLoader->CancelLoadURLTimer(); + CancelRefreshURLTimers(); return NS_OK; } return NS_ERROR_FAILURE; @@ -1084,14 +1106,14 @@ nsWebShell::GoTo(PRInt32 aHistoryIndex) mDocLoader->Stop(); // Cancel any timers that were set for this loader. - mDocLoader->CancelLoadURLTimer(); + CancelRefreshURLTimers(); rv = mDocLoader->LoadURL(urlSpec, // URL string nsnull, // Command this, // Container nsnull, // Post Data nsnull, // Extra Info... - mObserver); // Observer + mObserver); // Observer } return rv; } @@ -1502,6 +1524,77 @@ nsWebShell::OnConnectionsComplete() return ret; } +/* For use with redirect/refresh url api */ +class refreshData { + public: + nsIWebShell* shell; + nsString* aUrlSpec; + PRBool repeat; + PRInt32 delay; +}; + +NS_IMETHODIMP +nsWebShell::RefreshURL(nsIURL* aURL, PRInt32 millis, PRBool repeat) +{ + NS_PRECONDITION((aURL != nsnull), "Null pointer"); + + refreshData *data= new refreshData(); + nsITimer *timer=nsnull; + + NS_PRECONDITION((nsnull != data), "Null pointer"); + + data->shell = this; + NS_ADDREF(data->shell); + data->aUrlSpec = new nsString(aURL->GetSpec()); + data->delay = millis; + data->repeat = repeat; + + /* Create the timer. */ + if (NS_OK == NS_NewTimer(&timer)) { + /* Add the timer to our array. */ + mRefreshments.AppendElement(timer); + timer->Init(nsWebShell::RefreshURLCallback, data, millis); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsWebShell::CancelRefreshURLTimers(void) { + PRInt32 count = mRefreshments.Count(); + PRInt32 tmp=0; + nsITimer* timer; + refreshData* data = nsnull; + + /* Right now all we can do is cancel all the timers for this webshell. */ + while (tmp < count) { + timer=(nsITimer*)mRefreshments.ElementAt(tmp); + /* ditch the mem allocated in/to data */ + data = (refreshData*)timer->GetClosure(); + if (data) { + NS_RELEASE(data->shell); + if (data->aUrlSpec) + delete data->aUrlSpec; + } + delete data; + + mRefreshments.RemoveElementAt(tmp); + if (timer) { + timer->Cancel(); + timer->Release(); + } + tmp++; + } + + return NS_OK; +} + +void nsWebShell::RefreshURLCallback(nsITimer* aTimer, void* aClosure) { + refreshData *data=(refreshData*)aClosure; + NS_PRECONDITION((data != nsnull), "Null pointer..."); + data->shell->LoadURL(*data->aUrlSpec, nsnull, PR_TRUE); +} + //---------------------------------------------------------------------- // Factory code for creating nsWebShell's diff --git a/mozilla/uriloader/base/nsDocLoader.cpp b/mozilla/uriloader/base/nsDocLoader.cpp index eee76466e45..451cb486b66 100644 --- a/mozilla/uriloader/base/nsDocLoader.cpp +++ b/mozilla/uriloader/base/nsDocLoader.cpp @@ -37,6 +37,7 @@ #include "nsITimer.h" #include "nsIDocumentLoaderObserver.h" #include "nsVoidArray.h" +#include "nsIHttpUrl.h" // XXX: Only needed for dummy factory... #include "nsIDocument.h" @@ -65,6 +66,9 @@ NS_DEFINE_IID(kIDocumentLoaderFactoryIID, NS_IDOCUMENTLOADERFACTORY_IID); NS_DEFINE_IID(kDocLoaderImplIID, NS_DOCLOADERIMPL_IID); NS_DEFINE_IID(kDocumentBindInfoIID, NS_DOCUMENTBINDINFO_IID); NS_DEFINE_IID(kRefreshURLIID, NS_IREFRESHURL_IID); +NS_DEFINE_IID(kHTTPURLIID, NS_IHTTPURL_IID); +NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + /* @@ -115,6 +119,7 @@ public: /* nsIRefreshURL interface methods... */ NS_IMETHOD RefreshURL(nsIURL* aURL, PRInt32 millis, PRBool repeat); + NS_IMETHOD CancelRefreshURLTimers(void); nsresult GetStatus(void) { return mStatus; } @@ -379,17 +384,6 @@ public: NS_IMETHOD LoadURL(const nsString& aURLSpec, nsIStreamListener* aListener); - NS_IMETHOD LoadURLOnTimer(const nsString& aURLSpec, - const char* aCommand, - nsIContentViewerContainer* aContainer, - nsIPostData* aPostData = nsnull, - nsISupports* aExtraInfo = nsnull, - nsIStreamObserver* anObserver = nsnull, - PRInt32 millis = 0, - PRBool repeat = 0); - - NS_IMETHOD CancelLoadURLTimer(void); - NS_IMETHOD Stop(void); NS_IMETHOD CreateDocumentLoader(nsIDocumentLoader** anInstance); @@ -397,8 +391,6 @@ public: void LoadURLComplete(nsISupports* loader); - static void RefreshURLCallback(nsITimer* aTimer, void* aClosure); - NS_IMETHOD AddObserver(nsIDocumentLoaderObserver *aObserver); NS_IMETHOD RemoveObserver(nsIDocumentLoaderObserver *aObserver); @@ -411,7 +403,6 @@ private: public: nsIDocumentLoaderFactory* m_DocFactory; - nsVoidArray* mRefreshments; protected: nsISupportsArray* m_LoadingDocsList; @@ -434,8 +425,6 @@ nsDocLoaderImpl::nsDocLoaderImpl(nsDocLoaderImpl* aParent) m_DocFactory = new nsDocFactoryImpl(); NS_ADDREF(m_DocFactory); - - mRefreshments = new nsVoidArray(); } @@ -582,92 +571,6 @@ done: return rv; } -class refreshData { - public: - nsIDocumentLoader* aLoader; - nsString* aURLSpec; - char* aCommand; - nsIContentViewerContainer* aContainer; - nsIPostData* aPostData; - nsISupports* aExtraInfo; - nsIStreamObserver* anObserver; -}; - -void nsDocLoaderImpl::RefreshURLCallback(nsITimer* aTimer, void* aClosure) { - - refreshData *data=(refreshData*)aClosure; - nsIDocumentLoader* aLoader=(nsIDocumentLoader*)data->aLoader; - - NS_PRECONDITION((data != nsnull), "Null pointer..."); - - /* make sure the url should still be loaded. */ - /* set the timer again */ - /* load the url */ - aLoader->LoadURL(*data->aURLSpec, - data->aCommand, - data->aContainer, - data->aPostData, - data->aExtraInfo, - data->anObserver); -} - -NS_IMETHODIMP -nsDocLoaderImpl::LoadURLOnTimer(const nsString& aURLSpec, - const char* aCommand, - nsIContentViewerContainer* aContainer, - nsIPostData* aPostData, - nsISupports* aExtraInfo, - nsIStreamObserver* anObserver, - PRInt32 millis, - PRBool repeat) { - - refreshData *data= new refreshData(); - nsITimer *timer=nsnull; - nsString com(aCommand); - nsString spec(aURLSpec); - - NS_PRECONDITION((nsnull != data), "Null pointer"); - - data->aLoader=this; - data->aURLSpec = new nsString(aURLSpec); - data->aCommand=com.ToNewCString(); - data->aContainer=aContainer; - data->aPostData=aPostData; - data->aExtraInfo=aExtraInfo; - data->anObserver=anObserver; - - /* Create the timer. */ - if (NS_OK == NS_NewTimer(&timer)) { - timer->Init(nsDocLoaderImpl::RefreshURLCallback, data, millis); - } - - /* Add the timer to our array. */ - mRefreshments->AppendElement(timer); - return NS_OK; -} - -NS_IMETHODIMP -nsDocLoaderImpl::CancelLoadURLTimer(void) { - PRInt32 count = mRefreshments->Count(); - PRInt32 tmp=0; - nsITimer* timer; - - /* Right now all we can do is cancel all the timers for this loader. - * We don't have access to the data to find a particular url to cancel. */ - while (tmp < count) { - timer=(nsITimer*)mRefreshments->ElementAt(tmp); - mRefreshments->RemoveElementAt(tmp); - if (timer) { - timer->Cancel(); - timer->Release(); - } - tmp++; - } - - return NS_OK; -} - - NS_IMETHODIMP nsDocLoaderImpl::Stop(void) { @@ -877,9 +780,28 @@ nsresult nsDocumentBindInfo::Bind(const nsString& aURLSpec, { nsresult rv; - rv = NS_NewURL(&m_Url, aURLSpec); - if (NS_OK != rv) { - return rv; + /* If this nsDocumentBindInfo was created with a container pointer. + * extract the nsISupports iface from it and create the url with + * the nsISupports pointer so the backend can have access to the front + * end nsIContentViewerContainer for refreshing urls. + */ + if (m_Container) { + nsISupports* container = nsnull; + rv = m_Container->QueryInterface(kISupportsIID, (void**)&container); + if (rv != NS_OK) { + return rv; + } + rv = NS_NewURL(&m_Url, aURLSpec, container); + NS_RELEASE(container); + container = nsnull; + if (NS_OK != rv) { + return rv; + } + } else { + rv = NS_NewURL(&m_Url, aURLSpec); + if (NS_OK != rv) { + return rv; + } } /* Store any POST data into the URL */ @@ -912,7 +834,6 @@ nsresult nsDocumentBindInfo::Bind(const nsString& aURLSpec, return rv; } - nsresult nsDocumentBindInfo::Stop(void) { mStatus = NS_BINDING_ABORTED; @@ -1136,19 +1057,42 @@ nsDocumentBindInfo::PromptPassword(const nsString &aText, NS_METHOD nsDocumentBindInfo::RefreshURL(nsIURL* aURL, PRInt32 millis, PRBool repeat) { - if (nsnull != m_DocLoader) { - return m_DocLoader->LoadURLOnTimer(aURL->GetSpec(), - m_Command, - m_Container, - nsnull, - m_ExtraInfo, - m_Observer, - millis, - repeat); + if (nsnull != m_Container) { + nsresult rv; + nsIRefreshUrl* refresher = nsnull; + + /* Delegate the actual refresh call up-to the container. */ + rv = m_Container->QueryInterface(kRefreshURLIID, (void**)&refresher); + + if (rv != NS_OK) { + PR_FALSE; + } + rv = refresher->RefreshURL(aURL, millis, repeat); + NS_RELEASE(refresher); + return rv; } return PR_FALSE; } +NS_METHOD +nsDocumentBindInfo::CancelRefreshURLTimers(void) +{ + if (nsnull != m_Container) { + nsresult rv; + nsIRefreshUrl* refresher = nsnull; + + /* Delegate the actual cancel call up-to the container. */ + rv = m_Container->QueryInterface(kRefreshURLIID, (void**)&refresher); + + if (rv != NS_OK) { + PR_FALSE; + } + rv = refresher->CancelRefreshURLTimers(); + NS_RELEASE(refresher); + return rv; + } + return PR_FALSE; +} /******************************************* * nsDocLoaderFactory diff --git a/mozilla/webshell/public/nsIDocumentLoader.h b/mozilla/webshell/public/nsIDocumentLoader.h index 28550f46e49..48aaf3f0ce7 100644 --- a/mozilla/webshell/public/nsIDocumentLoader.h +++ b/mozilla/webshell/public/nsIDocumentLoader.h @@ -76,17 +76,6 @@ public: NS_IMETHOD LoadURL(const nsString& aURLSpec, nsIStreamListener* aListener) = 0; - NS_IMETHOD LoadURLOnTimer(const nsString& aURLSpec, - const char* aCommand, - nsIContentViewerContainer* aContainer, - nsIPostData* aPostData = nsnull, - nsISupports* aExtraInfo = nsnull, - nsIStreamObserver* anObserver = nsnull, - PRInt32 millis = 0, - PRBool repeat = 0) = 0; - - NS_IMETHOD CancelLoadURLTimer(void) = 0; - NS_IMETHOD Stop(void) = 0; NS_IMETHOD CreateDocumentLoader(nsIDocumentLoader** anInstance) = 0; diff --git a/mozilla/webshell/src/nsDocLoader.cpp b/mozilla/webshell/src/nsDocLoader.cpp index eee76466e45..451cb486b66 100644 --- a/mozilla/webshell/src/nsDocLoader.cpp +++ b/mozilla/webshell/src/nsDocLoader.cpp @@ -37,6 +37,7 @@ #include "nsITimer.h" #include "nsIDocumentLoaderObserver.h" #include "nsVoidArray.h" +#include "nsIHttpUrl.h" // XXX: Only needed for dummy factory... #include "nsIDocument.h" @@ -65,6 +66,9 @@ NS_DEFINE_IID(kIDocumentLoaderFactoryIID, NS_IDOCUMENTLOADERFACTORY_IID); NS_DEFINE_IID(kDocLoaderImplIID, NS_DOCLOADERIMPL_IID); NS_DEFINE_IID(kDocumentBindInfoIID, NS_DOCUMENTBINDINFO_IID); NS_DEFINE_IID(kRefreshURLIID, NS_IREFRESHURL_IID); +NS_DEFINE_IID(kHTTPURLIID, NS_IHTTPURL_IID); +NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + /* @@ -115,6 +119,7 @@ public: /* nsIRefreshURL interface methods... */ NS_IMETHOD RefreshURL(nsIURL* aURL, PRInt32 millis, PRBool repeat); + NS_IMETHOD CancelRefreshURLTimers(void); nsresult GetStatus(void) { return mStatus; } @@ -379,17 +384,6 @@ public: NS_IMETHOD LoadURL(const nsString& aURLSpec, nsIStreamListener* aListener); - NS_IMETHOD LoadURLOnTimer(const nsString& aURLSpec, - const char* aCommand, - nsIContentViewerContainer* aContainer, - nsIPostData* aPostData = nsnull, - nsISupports* aExtraInfo = nsnull, - nsIStreamObserver* anObserver = nsnull, - PRInt32 millis = 0, - PRBool repeat = 0); - - NS_IMETHOD CancelLoadURLTimer(void); - NS_IMETHOD Stop(void); NS_IMETHOD CreateDocumentLoader(nsIDocumentLoader** anInstance); @@ -397,8 +391,6 @@ public: void LoadURLComplete(nsISupports* loader); - static void RefreshURLCallback(nsITimer* aTimer, void* aClosure); - NS_IMETHOD AddObserver(nsIDocumentLoaderObserver *aObserver); NS_IMETHOD RemoveObserver(nsIDocumentLoaderObserver *aObserver); @@ -411,7 +403,6 @@ private: public: nsIDocumentLoaderFactory* m_DocFactory; - nsVoidArray* mRefreshments; protected: nsISupportsArray* m_LoadingDocsList; @@ -434,8 +425,6 @@ nsDocLoaderImpl::nsDocLoaderImpl(nsDocLoaderImpl* aParent) m_DocFactory = new nsDocFactoryImpl(); NS_ADDREF(m_DocFactory); - - mRefreshments = new nsVoidArray(); } @@ -582,92 +571,6 @@ done: return rv; } -class refreshData { - public: - nsIDocumentLoader* aLoader; - nsString* aURLSpec; - char* aCommand; - nsIContentViewerContainer* aContainer; - nsIPostData* aPostData; - nsISupports* aExtraInfo; - nsIStreamObserver* anObserver; -}; - -void nsDocLoaderImpl::RefreshURLCallback(nsITimer* aTimer, void* aClosure) { - - refreshData *data=(refreshData*)aClosure; - nsIDocumentLoader* aLoader=(nsIDocumentLoader*)data->aLoader; - - NS_PRECONDITION((data != nsnull), "Null pointer..."); - - /* make sure the url should still be loaded. */ - /* set the timer again */ - /* load the url */ - aLoader->LoadURL(*data->aURLSpec, - data->aCommand, - data->aContainer, - data->aPostData, - data->aExtraInfo, - data->anObserver); -} - -NS_IMETHODIMP -nsDocLoaderImpl::LoadURLOnTimer(const nsString& aURLSpec, - const char* aCommand, - nsIContentViewerContainer* aContainer, - nsIPostData* aPostData, - nsISupports* aExtraInfo, - nsIStreamObserver* anObserver, - PRInt32 millis, - PRBool repeat) { - - refreshData *data= new refreshData(); - nsITimer *timer=nsnull; - nsString com(aCommand); - nsString spec(aURLSpec); - - NS_PRECONDITION((nsnull != data), "Null pointer"); - - data->aLoader=this; - data->aURLSpec = new nsString(aURLSpec); - data->aCommand=com.ToNewCString(); - data->aContainer=aContainer; - data->aPostData=aPostData; - data->aExtraInfo=aExtraInfo; - data->anObserver=anObserver; - - /* Create the timer. */ - if (NS_OK == NS_NewTimer(&timer)) { - timer->Init(nsDocLoaderImpl::RefreshURLCallback, data, millis); - } - - /* Add the timer to our array. */ - mRefreshments->AppendElement(timer); - return NS_OK; -} - -NS_IMETHODIMP -nsDocLoaderImpl::CancelLoadURLTimer(void) { - PRInt32 count = mRefreshments->Count(); - PRInt32 tmp=0; - nsITimer* timer; - - /* Right now all we can do is cancel all the timers for this loader. - * We don't have access to the data to find a particular url to cancel. */ - while (tmp < count) { - timer=(nsITimer*)mRefreshments->ElementAt(tmp); - mRefreshments->RemoveElementAt(tmp); - if (timer) { - timer->Cancel(); - timer->Release(); - } - tmp++; - } - - return NS_OK; -} - - NS_IMETHODIMP nsDocLoaderImpl::Stop(void) { @@ -877,9 +780,28 @@ nsresult nsDocumentBindInfo::Bind(const nsString& aURLSpec, { nsresult rv; - rv = NS_NewURL(&m_Url, aURLSpec); - if (NS_OK != rv) { - return rv; + /* If this nsDocumentBindInfo was created with a container pointer. + * extract the nsISupports iface from it and create the url with + * the nsISupports pointer so the backend can have access to the front + * end nsIContentViewerContainer for refreshing urls. + */ + if (m_Container) { + nsISupports* container = nsnull; + rv = m_Container->QueryInterface(kISupportsIID, (void**)&container); + if (rv != NS_OK) { + return rv; + } + rv = NS_NewURL(&m_Url, aURLSpec, container); + NS_RELEASE(container); + container = nsnull; + if (NS_OK != rv) { + return rv; + } + } else { + rv = NS_NewURL(&m_Url, aURLSpec); + if (NS_OK != rv) { + return rv; + } } /* Store any POST data into the URL */ @@ -912,7 +834,6 @@ nsresult nsDocumentBindInfo::Bind(const nsString& aURLSpec, return rv; } - nsresult nsDocumentBindInfo::Stop(void) { mStatus = NS_BINDING_ABORTED; @@ -1136,19 +1057,42 @@ nsDocumentBindInfo::PromptPassword(const nsString &aText, NS_METHOD nsDocumentBindInfo::RefreshURL(nsIURL* aURL, PRInt32 millis, PRBool repeat) { - if (nsnull != m_DocLoader) { - return m_DocLoader->LoadURLOnTimer(aURL->GetSpec(), - m_Command, - m_Container, - nsnull, - m_ExtraInfo, - m_Observer, - millis, - repeat); + if (nsnull != m_Container) { + nsresult rv; + nsIRefreshUrl* refresher = nsnull; + + /* Delegate the actual refresh call up-to the container. */ + rv = m_Container->QueryInterface(kRefreshURLIID, (void**)&refresher); + + if (rv != NS_OK) { + PR_FALSE; + } + rv = refresher->RefreshURL(aURL, millis, repeat); + NS_RELEASE(refresher); + return rv; } return PR_FALSE; } +NS_METHOD +nsDocumentBindInfo::CancelRefreshURLTimers(void) +{ + if (nsnull != m_Container) { + nsresult rv; + nsIRefreshUrl* refresher = nsnull; + + /* Delegate the actual cancel call up-to the container. */ + rv = m_Container->QueryInterface(kRefreshURLIID, (void**)&refresher); + + if (rv != NS_OK) { + PR_FALSE; + } + rv = refresher->CancelRefreshURLTimers(); + NS_RELEASE(refresher); + return rv; + } + return PR_FALSE; +} /******************************************* * nsDocLoaderFactory diff --git a/mozilla/webshell/src/nsWebShell.cpp b/mozilla/webshell/src/nsWebShell.cpp index 332f3c37275..57e1ec53dcc 100644 --- a/mozilla/webshell/src/nsWebShell.cpp +++ b/mozilla/webshell/src/nsWebShell.cpp @@ -41,6 +41,8 @@ #include "nsPluginsCID.h" #include "nsIPref.h" #include "nsIBrowserWindow.h" +#include "nsIRefreshUrl.h" +#include "nsITimer.h" #include "prlog.h" @@ -91,7 +93,8 @@ class nsWebShell : public nsIWebShell, public nsIWebShellContainer, public nsILinkHandler, public nsIScriptContextOwner, - public nsIDocumentLoaderObserver + public nsIDocumentLoaderObserver, + public nsIRefreshUrl { public: nsWebShell(); @@ -193,6 +196,11 @@ public: // nsIDocumentLoaderObserver NS_IMETHOD OnConnectionsComplete(); + // nsIRefreshURL interface methods... + NS_IMETHOD RefreshURL(nsIURL* aURL, PRInt32 millis, PRBool repeat); + NS_IMETHOD CancelRefreshURLTimers(void); + + // nsWebShell void HandleLinkClickEvent(const PRUnichar* aURLSpec, const PRUnichar* aTargetSpec, @@ -202,6 +210,8 @@ public: nsIWebShell* GetTarget(const PRUnichar* aName); + static void RefreshURLCallback(nsITimer* aTimer, void* aClosure); + static nsEventStatus PR_CALLBACK HandleEvent(nsGUIEvent *aEvent); static nsresult CreatePluginHost(void); @@ -234,6 +244,7 @@ protected: nsScrollPreference mScrollPref; PRInt32 mMarginWidth; PRInt32 mMarginHeight; + nsVoidArray mRefreshments; void ReleaseChildren(); @@ -267,6 +278,7 @@ static NS_DEFINE_IID(kCPluginHostCID, NS_PLUGIN_HOST_CID); static NS_DEFINE_IID(kIBrowserWindowIID, NS_IBROWSER_WINDOW_IID); static NS_DEFINE_IID(kIDocumentLoaderObserverIID, NS_IDOCUMENT_LOADER_OBSERVER_IID); static NS_DEFINE_IID(kIDocumentViewerIID, NS_IDOCUMENT_VIEWER_IID); +static NS_DEFINE_IID(kRefreshURLIID, NS_IREFRESHURL_IID); // XXX not sure static NS_DEFINE_IID(kILinkHandlerIID, NS_ILINKHANDLER_IID); @@ -317,11 +329,11 @@ nsWebShell::~nsWebShell() // Stop any pending document loads and destroy the loader... if (nsnull != mDocLoader) { mDocLoader->Stop(); - // Cancel any timers that were set for this loader. - mDocLoader->CancelLoadURLTimer(); mDocLoader->RemoveObserver((nsIDocumentLoaderObserver*)this); NS_RELEASE(mDocLoader); } + // Cancel any timers that were set for this loader. + CancelRefreshURLTimers(); NS_IF_RELEASE(mInnerWindow); @@ -398,6 +410,11 @@ nsWebShell::QueryInterface(REFNSIID aIID, void** aInstancePtr) AddRef(); return NS_OK; } + if (aIID.Equals(kRefreshURLIID)) { + *aInstancePtr = (void*)(nsIRefreshUrl*)this; + AddRef(); + return NS_OK; + } if (nsnull != mInnerWindow) { return mInnerWindow->QueryInterface(aIID, aInstancePtr); } @@ -560,7 +577,7 @@ nsWebShell::Destroy() mDocLoader->Stop(); // Cancel any timers that were set for this loader. - mDocLoader->CancelLoadURLTimer(); + CancelRefreshURLTimers(); SetContainer(nsnull); SetObserver(nsnull); @@ -991,12 +1008,17 @@ nsWebShell::LoadURL(const PRUnichar *aURLSpec, Stop(); + // Cancel any timers that were set for this loader. + CancelRefreshURLTimers(); + rv = mDocLoader->LoadURL(urlSpec, // URL string nsnull, // Command this, // Container aPostData, // Post Data nsnull, // Extra Info... - mObserver); // Observer + mObserver); // Observer + + return rv; } @@ -1007,7 +1029,7 @@ NS_IMETHODIMP nsWebShell::Stop(void) mDocLoader->Stop(); // Cancel any timers that were set for this loader. - mDocLoader->CancelLoadURLTimer(); + CancelRefreshURLTimers(); return NS_OK; } return NS_ERROR_FAILURE; @@ -1084,14 +1106,14 @@ nsWebShell::GoTo(PRInt32 aHistoryIndex) mDocLoader->Stop(); // Cancel any timers that were set for this loader. - mDocLoader->CancelLoadURLTimer(); + CancelRefreshURLTimers(); rv = mDocLoader->LoadURL(urlSpec, // URL string nsnull, // Command this, // Container nsnull, // Post Data nsnull, // Extra Info... - mObserver); // Observer + mObserver); // Observer } return rv; } @@ -1502,6 +1524,77 @@ nsWebShell::OnConnectionsComplete() return ret; } +/* For use with redirect/refresh url api */ +class refreshData { + public: + nsIWebShell* shell; + nsString* aUrlSpec; + PRBool repeat; + PRInt32 delay; +}; + +NS_IMETHODIMP +nsWebShell::RefreshURL(nsIURL* aURL, PRInt32 millis, PRBool repeat) +{ + NS_PRECONDITION((aURL != nsnull), "Null pointer"); + + refreshData *data= new refreshData(); + nsITimer *timer=nsnull; + + NS_PRECONDITION((nsnull != data), "Null pointer"); + + data->shell = this; + NS_ADDREF(data->shell); + data->aUrlSpec = new nsString(aURL->GetSpec()); + data->delay = millis; + data->repeat = repeat; + + /* Create the timer. */ + if (NS_OK == NS_NewTimer(&timer)) { + /* Add the timer to our array. */ + mRefreshments.AppendElement(timer); + timer->Init(nsWebShell::RefreshURLCallback, data, millis); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsWebShell::CancelRefreshURLTimers(void) { + PRInt32 count = mRefreshments.Count(); + PRInt32 tmp=0; + nsITimer* timer; + refreshData* data = nsnull; + + /* Right now all we can do is cancel all the timers for this webshell. */ + while (tmp < count) { + timer=(nsITimer*)mRefreshments.ElementAt(tmp); + /* ditch the mem allocated in/to data */ + data = (refreshData*)timer->GetClosure(); + if (data) { + NS_RELEASE(data->shell); + if (data->aUrlSpec) + delete data->aUrlSpec; + } + delete data; + + mRefreshments.RemoveElementAt(tmp); + if (timer) { + timer->Cancel(); + timer->Release(); + } + tmp++; + } + + return NS_OK; +} + +void nsWebShell::RefreshURLCallback(nsITimer* aTimer, void* aClosure) { + refreshData *data=(refreshData*)aClosure; + NS_PRECONDITION((data != nsnull), "Null pointer..."); + data->shell->LoadURL(*data->aUrlSpec, nsnull, PR_TRUE); +} + //---------------------------------------------------------------------- // Factory code for creating nsWebShell's