Fix for bug #s 13329 15236. Back and forward eratic in frame pages.

approved by chofmann


git-svn-id: svn://10.0.0.236/branches/SeaMonkey_M10_BRANCH@49585 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
radha%netscape.com
1999-10-01 19:27:38 +00:00
parent ca1aff4d3d
commit b7bfdcdf30
5 changed files with 228 additions and 130 deletions

View File

@@ -1994,6 +1994,11 @@ nsWebShell::DoLoadURL(nsIURI * aUri,
nsresult rv = NS_OK;
rv = aUri->GetSpec(getter_Copies(urlSpec));
if (NS_FAILED(rv)) return rv;
/* mURL is being set the value again so that calls to DoLoadURL() from Viewer
* will work right. This statement could go to Goto(), but that really is
* Vidur's call
*/
mURL = urlSpec;
mReferrer = aReferrer;
@@ -2105,7 +2110,6 @@ nsWebShell::DoLoadURL(nsIURI * aUri,
/* WebShell was primarily passing the buck when it came to streamObserver.
* So, pass on the observer which is already a streamObserver to DocLoder.
* - Radha
*/
return mDocLoader->LoadDocument(aUri, // URL string
@@ -2146,53 +2150,7 @@ nsWebShell::LoadURI(nsIURI * aUri,
rv = aUri->GetSpec(getter_Copies(spec));
if (NS_FAILED(rv)) return rv;
/*
* Before the new page is added to the session history,
* save the history information of the previous page in
* session history
*/
nsCOMPtr<nsISupports> historyState;
// Get the history object for the previous page.
rv = GetHistoryState(getter_AddRefs(historyState));
nsCOMPtr<nsIWebShell> rootWebShell;
rv = GetRootWebShell(*getter_AddRefs(rootWebShell));
if (NS_SUCCEEDED(rv) && rootWebShell) {
nsCOMPtr<nsISessionHistory> shist;
rv = rootWebShell->GetSessionHistory(*getter_AddRefs(shist));
if (NS_SUCCEEDED(rv) && shist) {
PRInt32 indix=0;
shist->getCurrentIndex(indix);
// Save it in session history
shist->SetHistoryObjectForIndex(indix, historyState);
}
}
/* If this is one of the frames, get it from the top level shell */
if (aModifyHistory) {
if (rootWebShell) {
nsCOMPtr<nsISessionHistory> shist;
rootWebShell->GetSessionHistory(*getter_AddRefs(shist));
/* Add yourself to the Session History */
if (shist) {
PRInt32 ret=0;
ret = shist->add(this);
}
}
}
/* Set the History state object for the current page in the
* presentation shell. If it is a new page being visited,
* aHistoryState is null. If the load is coming from
* session History, it will be set to the cached history object by
* session History.
*/
SetHistoryState(aHistoryState);
nsString* url = new nsString(uriSpec);
if (aModifyHistory) {
// Discard part of history that is no longer reachable
@@ -2219,9 +2177,6 @@ nsWebShell::LoadURI(nsIURI * aUri,
ShowHistory();
/* The session History may have changed the URL. So pass on the
* right one for loading
*/
// Give web-shell-container right of refusal
if (nsnull != mContainer) {
nsAutoString str(spec);
@@ -2250,6 +2205,7 @@ nsWebShell::LoadURL(const PRUnichar *aURLSpec,
nsAutoString urlStr(aURLSpec);
// first things first. try to create a uri out of the string.
nsCOMPtr<nsIURI> uri;
nsXPIDLCString spec;
rv = NS_NewURI(getter_AddRefs(uri), urlStr, nsnull);
if (NS_FAILED(rv)) {
// no dice.
@@ -2300,37 +2256,92 @@ nsWebShell::LoadURL(const PRUnichar *aURLSpec,
//Take care of mailto: url
PRBool isMail= PR_FALSE;
rv = uri->GetSpec(getter_Copies(spec));
if (NS_FAILED(rv))
return rv;
nsAutoString urlAStr(aURLSpec);
nsAutoString urlAStr(spec);
if ((urlAStr.Find("mailto", PR_TRUE)) >= 0) {
isMail = PR_TRUE;
}
// Get hold of Root webshell
nsCOMPtr<nsIWebShell> root;
nsCOMPtr<nsISessionHistory> shist;
rv = GetRootWebShell(*getter_AddRefs(root));
// Get hold of session History
if (NS_SUCCEEDED(rv) && root) {
root->GetSessionHistory(*getter_AddRefs(shist));
}
/* Ask the URL dispatcher to take care of this URL only if it is a
* mailto: link clicked inside a browser or any link clicked
* inside a *non-browser* window. Note this mechanism s'd go away once
* we have the protocol registry and window manager available
* mailto: link clicked inside a browser. Note this mechanism s'd go
* away once we have URL dispatcher in place.
*/
if (NS_SUCCEEDED(rv) && root && isMail) {
if (root && isMail) {
//Ask the url Dispatcher to load the appropriate component for the URL.
nsCOMPtr<nsIUrlDispatcher> urlDispatcher;
rv = root->GetUrlDispatcher(*getter_AddRefs(urlDispatcher));
if (NS_SUCCEEDED(rv) && urlDispatcher) {
printf("calling HandleUrl\n");
urlDispatcher->HandleUrl(LinkCommand.GetUnicode(),
urlAStr.GetUnicode(), aPostDataStream);
return NS_OK;
}
}
/*
* Before the new page is added to the session history,
* save the history information of the previous page in
* session history
*/
nsCOMPtr<nsISupports> historyState=nsnull;
rv = GetHistoryState(getter_AddRefs(historyState));
// Get the history object for the previous page.
if (NS_SUCCEEDED(rv) && shist) {
PRInt32 indix=0;
shist->getCurrentIndex(indix);
// Save it in session history
shist->SetHistoryObjectForIndex(indix, historyState);
}
/* Set the History state object for the current page in the
* presentation shell. If it is a new page being visited,
* aHistoryState is null. If the load is coming from
* session History, it will be set to the cached history object by
* session History.
*/
SetHistoryState(aHistoryState);
/*
* Set mURL to spec so that session history can get
* hold of the url and change it if it has to.
* See comments below.
*/
mURL = spec;
/* Add the page to session history */
if (aModifyHistory && shist) {
PRInt32 ret;
ret = shist->add(this);
}
/* If we are going "Back" from a non-frame page to a frame page,
* session history will change the mURL to the right value
* for smoother redraw. So, create a new nsIURI based on mURL,
* so that it will work right in such situations.
*/
nsAutoString urlstr(mURL);
nsCOMPtr<nsIURI> newURI;
rv = NS_NewURI(getter_AddRefs(newURI), urlstr, nsnull);
if (NS_SUCCEEDED(rv)) {
// now that we have a uri, call the REAL LoadURI method which requires a nsIURI.
return LoadURI(newURI, aCommand, aPostDataStream, aModifyHistory, aType, aLocalIP, aHistoryState, aReferrer);
}
return rv;
// now that we have a uri, call the REAL LoadURI method which requires a nsIURI.
return LoadURI(uri, aCommand, aPostDataStream, aModifyHistory, aType, aLocalIP, aHistoryState, aReferrer);
}
@@ -2789,6 +2800,7 @@ nsWebShell::GetHistoryState(nsISupports** aLayoutHistoryState)
rv = docv->GetPresShell(*getter_AddRefs(shell));
if (NS_SUCCEEDED(rv)) {
rv = shell->GetHistoryState((nsILayoutHistoryState**) aLayoutHistoryState);
NS_ADDREF(*aLayoutHistoryState);
}
}
}

View File

@@ -1994,6 +1994,11 @@ nsWebShell::DoLoadURL(nsIURI * aUri,
nsresult rv = NS_OK;
rv = aUri->GetSpec(getter_Copies(urlSpec));
if (NS_FAILED(rv)) return rv;
/* mURL is being set the value again so that calls to DoLoadURL() from Viewer
* will work right. This statement could go to Goto(), but that really is
* Vidur's call
*/
mURL = urlSpec;
mReferrer = aReferrer;
@@ -2105,7 +2110,6 @@ nsWebShell::DoLoadURL(nsIURI * aUri,
/* WebShell was primarily passing the buck when it came to streamObserver.
* So, pass on the observer which is already a streamObserver to DocLoder.
* - Radha
*/
return mDocLoader->LoadDocument(aUri, // URL string
@@ -2146,53 +2150,7 @@ nsWebShell::LoadURI(nsIURI * aUri,
rv = aUri->GetSpec(getter_Copies(spec));
if (NS_FAILED(rv)) return rv;
/*
* Before the new page is added to the session history,
* save the history information of the previous page in
* session history
*/
nsCOMPtr<nsISupports> historyState;
// Get the history object for the previous page.
rv = GetHistoryState(getter_AddRefs(historyState));
nsCOMPtr<nsIWebShell> rootWebShell;
rv = GetRootWebShell(*getter_AddRefs(rootWebShell));
if (NS_SUCCEEDED(rv) && rootWebShell) {
nsCOMPtr<nsISessionHistory> shist;
rv = rootWebShell->GetSessionHistory(*getter_AddRefs(shist));
if (NS_SUCCEEDED(rv) && shist) {
PRInt32 indix=0;
shist->getCurrentIndex(indix);
// Save it in session history
shist->SetHistoryObjectForIndex(indix, historyState);
}
}
/* If this is one of the frames, get it from the top level shell */
if (aModifyHistory) {
if (rootWebShell) {
nsCOMPtr<nsISessionHistory> shist;
rootWebShell->GetSessionHistory(*getter_AddRefs(shist));
/* Add yourself to the Session History */
if (shist) {
PRInt32 ret=0;
ret = shist->add(this);
}
}
}
/* Set the History state object for the current page in the
* presentation shell. If it is a new page being visited,
* aHistoryState is null. If the load is coming from
* session History, it will be set to the cached history object by
* session History.
*/
SetHistoryState(aHistoryState);
nsString* url = new nsString(uriSpec);
if (aModifyHistory) {
// Discard part of history that is no longer reachable
@@ -2219,9 +2177,6 @@ nsWebShell::LoadURI(nsIURI * aUri,
ShowHistory();
/* The session History may have changed the URL. So pass on the
* right one for loading
*/
// Give web-shell-container right of refusal
if (nsnull != mContainer) {
nsAutoString str(spec);
@@ -2250,6 +2205,7 @@ nsWebShell::LoadURL(const PRUnichar *aURLSpec,
nsAutoString urlStr(aURLSpec);
// first things first. try to create a uri out of the string.
nsCOMPtr<nsIURI> uri;
nsXPIDLCString spec;
rv = NS_NewURI(getter_AddRefs(uri), urlStr, nsnull);
if (NS_FAILED(rv)) {
// no dice.
@@ -2300,37 +2256,92 @@ nsWebShell::LoadURL(const PRUnichar *aURLSpec,
//Take care of mailto: url
PRBool isMail= PR_FALSE;
rv = uri->GetSpec(getter_Copies(spec));
if (NS_FAILED(rv))
return rv;
nsAutoString urlAStr(aURLSpec);
nsAutoString urlAStr(spec);
if ((urlAStr.Find("mailto", PR_TRUE)) >= 0) {
isMail = PR_TRUE;
}
// Get hold of Root webshell
nsCOMPtr<nsIWebShell> root;
nsCOMPtr<nsISessionHistory> shist;
rv = GetRootWebShell(*getter_AddRefs(root));
// Get hold of session History
if (NS_SUCCEEDED(rv) && root) {
root->GetSessionHistory(*getter_AddRefs(shist));
}
/* Ask the URL dispatcher to take care of this URL only if it is a
* mailto: link clicked inside a browser or any link clicked
* inside a *non-browser* window. Note this mechanism s'd go away once
* we have the protocol registry and window manager available
* mailto: link clicked inside a browser. Note this mechanism s'd go
* away once we have URL dispatcher in place.
*/
if (NS_SUCCEEDED(rv) && root && isMail) {
if (root && isMail) {
//Ask the url Dispatcher to load the appropriate component for the URL.
nsCOMPtr<nsIUrlDispatcher> urlDispatcher;
rv = root->GetUrlDispatcher(*getter_AddRefs(urlDispatcher));
if (NS_SUCCEEDED(rv) && urlDispatcher) {
printf("calling HandleUrl\n");
urlDispatcher->HandleUrl(LinkCommand.GetUnicode(),
urlAStr.GetUnicode(), aPostDataStream);
return NS_OK;
}
}
/*
* Before the new page is added to the session history,
* save the history information of the previous page in
* session history
*/
nsCOMPtr<nsISupports> historyState=nsnull;
rv = GetHistoryState(getter_AddRefs(historyState));
// Get the history object for the previous page.
if (NS_SUCCEEDED(rv) && shist) {
PRInt32 indix=0;
shist->getCurrentIndex(indix);
// Save it in session history
shist->SetHistoryObjectForIndex(indix, historyState);
}
/* Set the History state object for the current page in the
* presentation shell. If it is a new page being visited,
* aHistoryState is null. If the load is coming from
* session History, it will be set to the cached history object by
* session History.
*/
SetHistoryState(aHistoryState);
/*
* Set mURL to spec so that session history can get
* hold of the url and change it if it has to.
* See comments below.
*/
mURL = spec;
/* Add the page to session history */
if (aModifyHistory && shist) {
PRInt32 ret;
ret = shist->add(this);
}
/* If we are going "Back" from a non-frame page to a frame page,
* session history will change the mURL to the right value
* for smoother redraw. So, create a new nsIURI based on mURL,
* so that it will work right in such situations.
*/
nsAutoString urlstr(mURL);
nsCOMPtr<nsIURI> newURI;
rv = NS_NewURI(getter_AddRefs(newURI), urlstr, nsnull);
if (NS_SUCCEEDED(rv)) {
// now that we have a uri, call the REAL LoadURI method which requires a nsIURI.
return LoadURI(newURI, aCommand, aPostDataStream, aModifyHistory, aType, aLocalIP, aHistoryState, aReferrer);
}
return rv;
// now that we have a uri, call the REAL LoadURI method which requires a nsIURI.
return LoadURI(uri, aCommand, aPostDataStream, aModifyHistory, aType, aLocalIP, aHistoryState, aReferrer);
}
@@ -2789,6 +2800,7 @@ nsWebShell::GetHistoryState(nsISupports** aLayoutHistoryState)
rv = docv->GetPresShell(*getter_AddRefs(shell));
if (NS_SUCCEEDED(rv)) {
rv = shell->GetHistoryState((nsILayoutHistoryState**) aLayoutHistoryState);
NS_ADDREF(*aLayoutHistoryState);
}
}
}

View File

@@ -158,6 +158,16 @@ public:
* Set the History state of the index
*/
NS_IMETHOD SetHistoryObjectForIndex(PRInt32 aIndex, nsISupports * aState) = 0;
/**
* Clear all history load flags
*/
NS_IMETHOD ClearLoadingFlags(void) = 0;
/**
* Reconcile history status with the actual page load status
*/
NS_IMETHOD UpdateStatus(nsIWebShell * aWebShell, nsresult aStatus) = 0;
};

View File

@@ -160,6 +160,7 @@ nsBrowserAppCore::nsBrowserAppCore()
mContentAreaDocLoader = nsnull;
mSHistory = nsnull;
mIsViewSource = PR_FALSE;
mIsLoadingHistory = PR_FALSE;
NS_INIT_REFCNT();
}
@@ -315,6 +316,11 @@ nsBrowserAppCore::Stop()
{
mContentAreaWebShell->Stop();
if (mIsLoadingHistory) {
mIsLoadingHistory = PR_FALSE;
if (mSHistory)
mSHistory->ClearLoadingFlags();
}
nsAutoString v( "false" );
// XXX: The throbber should be turned off when the OnStopDocumentLoad
// notification is received
@@ -949,6 +955,12 @@ nsBrowserAppCore::LoadUrl(const PRUnichar *aUrl)
{
nsresult rv = NS_OK;
if (mIsLoadingHistory) {
mIsLoadingHistory = PR_FALSE;
if (mSHistory) {
mSHistory->ClearLoadingFlags();
}
}
/* Ask nsWebShell to load the URl */
if ( mIsViewSource ) {
// Viewing source, load with "view-source" command.
@@ -1299,6 +1311,18 @@ nsBrowserAppCore::OnStartDocumentLoad(nsIDocumentLoader* aLoader, nsIURI* aURL,
//Disable the reload button
setAttribute(mWebShell, "canReload", "disabled", trueStr);
PRBool result=PR_TRUE;
// Check with sessionHistory if you can go forward
canForward(result);
setAttribute(mWebShell, "canGoForward", "disabled", (result == PR_TRUE) ? "" : "true");
// Check with sessionHistory if you can go back
canBack(result);
setAttribute(mWebShell, "canGoBack", "disabled", (result == PR_TRUE) ? "" : "true");
#ifdef NECKO
nsCRT::free(url);
@@ -1381,6 +1405,16 @@ nsBrowserAppCore::OnEndDocumentLoad(nsIDocumentLoader* aLoader, nsIChannel* chan
}
}
/* Inform Session History about the status of the page load */
if (mSHistory) {
mSHistory->UpdateStatus(webshell, aStatus);
}
if (mIsLoadingHistory) {
if (mSHistory)
mSHistory->ClearLoadingFlags();
mIsLoadingHistory=PR_FALSE;
}
/* If this is a frame, don't do any of the Global History
* & observer thingy
*/
@@ -1420,9 +1454,6 @@ nsBrowserAppCore::OnEndDocumentLoad(nsIDocumentLoader* aLoader, nsIChannel* chan
fflush(stdout);
}
} //if (!isFrame)
#ifdef DEBUG_warren
char* urls;
@@ -1441,7 +1472,7 @@ nsBrowserAppCore::OnEndDocumentLoad(nsIDocumentLoader* aLoader, nsIChannel* chan
setAttribute( mWebShell, "Browser:Throbber", "busy", "false" );
PRBool result=PR_TRUE;
#if 0
// Check with sessionHistory if you can go forward
canForward(result);
setAttribute(mWebShell, "canGoForward", "disabled", (result == PR_TRUE) ? "" : "true");
@@ -1450,7 +1481,7 @@ nsBrowserAppCore::OnEndDocumentLoad(nsIDocumentLoader* aLoader, nsIChannel* chan
// Check with sessionHistory if you can go back
canBack(result);
setAttribute(mWebShell, "canGoBack", "disabled", (result == PR_TRUE) ? "" : "true");
#endif /* 0 */
//Disable the Stop button
setAttribute( mWebShell, "canStop", "disabled", "true" );
@@ -1627,19 +1658,31 @@ nsBrowserAppCore::OnEndURLLoad(nsIDocumentLoader* loader,
NS_IMETHODIMP
nsBrowserAppCore::GoBack(nsIWebShell * aPrev)
{
if (mIsLoadingHistory) {
mIsLoadingHistory = PR_FALSE;
if (mSHistory)
mSHistory->ClearLoadingFlags();
}
mIsLoadingHistory = PR_TRUE;
if (mSHistory) {
mSHistory->GoBack(aPrev);
}
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP
nsBrowserAppCore::GoForward(nsIWebShell * aPrev)
{
if (mIsLoadingHistory) {
mIsLoadingHistory = PR_FALSE;
if (mSHistory)
mSHistory->ClearLoadingFlags();
}
mIsLoadingHistory = PR_TRUE;
if (mSHistory) {
mSHistory->GoForward(aPrev);
}
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP
@@ -1649,9 +1692,15 @@ nsBrowserAppCore::Reload(nsIWebShell * aPrev, nsURLReloadType aType)
nsBrowserAppCore::Reload(nsIWebShell * aPrev, nsLoadFlags aType)
#endif // NECKO
{
if (mSHistory)
mSHistory->Reload(aPrev, aType);
return NS_OK;
if (mIsLoadingHistory) {
mIsLoadingHistory = PR_FALSE;
if (mSHistory)
mSHistory->ClearLoadingFlags();
}
mIsLoadingHistory = PR_TRUE;
if (mSHistory)
mSHistory->Reload(aPrev, aType);
return NS_OK;
}
NS_IMETHODIMP
@@ -1672,6 +1721,12 @@ nsBrowserAppCore::Goto(PRInt32 aGotoIndex, nsIWebShell * aPrev, PRBool aIsReload
return rv;
}
NS_IMETHODIMP
nsBrowserInstance::ClearLoadingFlags()
{
mIsLoadingHistory = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsBrowserAppCore::SetLoadingFlag(PRBool aFlag)
@@ -1679,6 +1734,10 @@ nsBrowserAppCore::SetLoadingFlag(PRBool aFlag)
return NS_OK;
}
NS_IMETHODIMP
nsBrowserInstance::UpdateStatus(nsIWebShell * aWebShell, nsresult aStatus) {
return NS_OK;
}
NS_IMETHODIMP
nsBrowserAppCore::GetLoadingFlag(PRBool &aFlag)

View File

@@ -136,6 +136,10 @@ class nsBrowserInstance : public nsIBrowserInstance,
NS_IMETHOD SetHistoryObjectForIndex(PRInt32 aIndex, nsISupports * aState);
NS_IMETHOD ClearLoadingFlags();
NS_IMETHOD UpdateStatus(nsIWebShell * aWebShell, nsresult aStatus);
protected:
NS_IMETHOD ExecuteScript(nsIScriptContext * aContext, const nsString& aScript);
void InitializeSearch(nsIFindComponent*);
@@ -162,6 +166,7 @@ class nsBrowserInstance : public nsIBrowserInstance,
nsCOMPtr<nsISupports> mSearchContext; // at last, something we really own
nsInstanceCounter mInstanceCounter;
PRBool mIsLoadingHistory;
#ifdef DEBUG_warren
PRIntervalTime mLoadStartTime;
#endif