Fix for bug #13329 . Back and forward not consistent all the time.

Fix already checked in to the M10 branch. Merging changes to tip.
This commit is contained in:
radha%netscape.com 1999-10-05 04:49:58 +00:00
parent a0d9a79a54
commit 98ab0bb7c2
6 changed files with 464 additions and 175 deletions

View File

@ -1436,7 +1436,6 @@ nsWebShell::HandleEvent(nsGUIEvent *aEvent)
return nsEventStatus_eIgnore;
}
NS_IMETHODIMP
nsWebShell::SetDocLoaderObserver(nsIDocumentLoaderObserver* anObserver)
{
@ -1978,6 +1977,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;
@ -2089,7 +2093,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
@ -2129,53 +2132,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
@ -2202,9 +2159,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);
@ -2233,6 +2187,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.
@ -2283,37 +2238,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);
}
@ -2772,6 +2782,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

@ -1436,7 +1436,6 @@ nsWebShell::HandleEvent(nsGUIEvent *aEvent)
return nsEventStatus_eIgnore;
}
NS_IMETHODIMP
nsWebShell::SetDocLoaderObserver(nsIDocumentLoaderObserver* anObserver)
{
@ -1978,6 +1977,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;
@ -2089,7 +2093,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
@ -2129,53 +2132,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
@ -2202,9 +2159,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);
@ -2233,6 +2187,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.
@ -2283,37 +2238,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);
}
@ -2772,6 +2782,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

@ -74,6 +74,11 @@ public:
*/
PRBool Load(nsIWebShell * aPrevEntry, PRBool aIsReload);
/**
* Compare the history object with the content Area
*/
PRBool Compare(nsIWebShell * aPrevEntry, PRBool aIsReload);
/**
* Destroy the historyentry
*/
@ -182,9 +187,7 @@ nsHistoryEntry::nsHistoryEntry()
mParent = nsnull;
mURL = nsnull;
mTitle = nsnull;
mHistoryState = nsnull;
mHistoryState = nsnull;
// NS_INIT_REFCNT();
}
@ -373,6 +376,8 @@ nsHistoryEntry::Create(nsIWebShell * aWebShell, nsHistoryEntry * aParent, nsISes
// Get the webshell's url.
aWebShell->GetURL(&url);
nsAutoString urlstr(url);
// save the webshell's URL in the history entry
SetURL(url);
@ -380,7 +385,7 @@ nsHistoryEntry::Create(nsIWebShell * aWebShell, nsHistoryEntry * aParent, nsISes
//Save the webshell id
SetWebShell(aWebShell);
if (APP_DEBUG) printf("SessionHistory::Create Creating Historyentry %x for webshell %x, parent entry = %x\n", (unsigned int)this, (unsigned int)aWebShell, (unsigned int) aParent);
if (APP_DEBUG) printf("SessionHistory::Create Creating Historyentry %x for webshell %x, url = %s parent entry = %x\n", (unsigned int)this, (unsigned int)aWebShell, urlstr.ToNewCString(), (unsigned int) aParent);
if (aParent)
aParent->AddChild(this);
@ -422,7 +427,6 @@ GenerateTree(nsIWebShell * aWebShell, nsHistoryEntry * aParent, nsISessionHistor
}
}
return hEntry;
}
@ -485,10 +489,8 @@ nsHistoryEntry::Load(nsIWebShell * aPrevEntry, PRBool aIsReload) {
cur->GetURL(&cURL);
cSURL = new nsString(cURL);
}
// NS_ADDREF(aPrevEntry);
if (!cur || !prev) {
return NS_ERROR_NULL_POINTER;
}
@ -529,12 +531,13 @@ nsHistoryEntry::Load(nsIWebShell * aPrevEntry, PRBool aIsReload) {
*/
if (APP_DEBUG) printf("Returning from Load(). Located a webshell with frame children\n");
return PR_TRUE;
}
}
return PR_TRUE;
}
else if (!isInSHist && isLoadingDoc) {
prev->SetURL(cURL);
if (APP_DEBUG) printf("Changing URL to %s in webshell\n", cSURL->ToNewCString());
return PR_TRUE;
}
}
}
@ -542,7 +545,96 @@ nsHistoryEntry::Load(nsIWebShell * aPrevEntry, PRBool aIsReload) {
/* Mark the changed flag to false. This is used in the end to determine
* whether we are done with the whole loading process for this history
*/
if (APP_DEBUG) printf("SessionHistory::Load URLs in webshells %x & %x match \n", (unsigned int) mWS, (unsigned int) prev);
if (APP_DEBUG) printf("SessionHistory::Load URLs in webshells %x & %x match \n", (unsigned int) mWS, (unsigned int) prev);
}
/* Make sure the child windows are in par */
PRInt32 cnt=0, ccnt=0, pcnt=0;
ccnt = cur->GetChildCnt();
prev->GetChildCount(pcnt);
/* If the current entry to be loaded and the one on page don't have
* the same # of children, maybe the one on screen is is in the process of
* building. Don't compare the children.
*/
cnt = ccnt;
if (pcnt < ccnt)
cnt = pcnt;
for (i=0; i<cnt; i++){
nsHistoryEntry *cChild=nsnull;
nsIWebShell * pChild=nsnull;
cur->GetChildAt(i, cChild); // historyentry
prev->ChildAt(i, pChild); //webshell
result = cChild->Load(pChild, PR_FALSE);
if (result)
break;
}
if (ccnt != pcnt)
result = PR_TRUE;
// NS_IF_RELEASE(aPrevEntry);
return result;
} /* Load */
/* Compare the history item with the content area */
PRBool
nsHistoryEntry::Compare(nsIWebShell * aPrevEntry, PRBool aIsReload) {
nsHistoryEntry * cur=nsnull;
PRBool urlChanged = PR_FALSE;
int i = 0;
//nsIWebShell * pWS = nsnull, *cWS=nsnull;
nsIWebShell *prev=nsnull;
PRBool result = PR_FALSE;
nsString* cSURL=nsnull, * pSURL=nsnull;
const PRUnichar * pURL=nsnull, * cURL=nsnull;
cur = this;
prev = aPrevEntry;
if (prev) {
prev->GetURL(&pURL);
pSURL = new nsString(pURL);
}
if (cur) {
cur->GetURL(&cURL);
cSURL = new nsString(cURL);
}
// NS_ADDREF(aPrevEntry);
if (!cur || !prev) {
return NS_ERROR_NULL_POINTER;
}
//Compare the URLs
{
if ((*pSURL) == cURL)
urlChanged = PR_FALSE;
else
urlChanged = PR_TRUE;
} // compareURLs
/* The URL to be loaded in it */
cur->GetURL(&cURL);
if (urlChanged /*|| aIsReload*/) {
if (APP_DEBUG)
printf("SessionHistory::Compare URLs in webshells %x & %x don't match \n", (unsigned int) mWS, (unsigned int) prev);
return PR_TRUE;
}
else if (!urlChanged ) {
/* Mark the changed flag to false. This is used in the end to determine
* whether we are done with the whole loading process for this history
*/
if (APP_DEBUG) printf("SessionHistory::Compare URLs in webshells %x & %x match \n", (unsigned int) mWS, (unsigned int) prev);
}
/* Make sure the child windows are in par */
@ -562,11 +654,9 @@ nsHistoryEntry::Load(nsIWebShell * aPrevEntry, PRBool aIsReload) {
for (i=0; i<cnt; i++){
nsHistoryEntry *cChild=nsnull;
nsIWebShell * pChild=nsnull;
cur->GetChildAt(i, cChild); // historyentry
prev->ChildAt(i, pChild); //webshell
result = cChild->Load(pChild, PR_FALSE);
result = cChild->Compare(pChild, PR_FALSE);
if (result)
break;
}
@ -577,7 +667,7 @@ nsHistoryEntry::Load(nsIWebShell * aPrevEntry, PRBool aIsReload) {
// NS_IF_RELEASE(aPrevEntry);
return result;
} /* Load */
} /* Compare */
nsHistoryEntry *
@ -719,6 +809,16 @@ public:
*/
NS_IMETHOD SetHistoryObjectForIndex(PRInt32 aIndex, nsISupports * aState);
/**
* Clear all history load flags
*/
NS_IMETHOD ClearLoadingFlags(void) ;
/**
* Reconcile history status with the actual page load status
*/
NS_IMETHOD UpdateStatus(nsIWebShell * aWebShell, nsresult aStatus);
protected:
virtual ~nsSessionHistory();
@ -798,11 +898,11 @@ nsSessionHistory::add(nsIWebShell * aWebShell)
if (!parent) {
if(mIsLoadingDoc) {
/* We are currently loading a history entry. Pass it to
* Load() to check if the URLs match. Load() will take care
* of differences in URL
*/
* Load() to check if the URLs match. Load() will take care
* of differences in URL
*/
nsresult ret = mHistoryEntryInLoad->Load(aWebShell, PR_FALSE);
nsresult ret = mHistoryEntryInLoad->Compare(aWebShell, PR_FALSE);
if (!ret) {
/* The URL in the webshell exactly matches with the
* one in history. Clear all flags and return.
@ -828,19 +928,19 @@ nsSessionHistory::add(nsIWebShell * aWebShell)
// Add the URL to the history
if ((mHistoryLength - (mHistoryCurrentIndex+1)) > 0) {
/* We are somewhere in the middle of the history and a
* new page was visited. Purge all entries from the current index
* till the end of the list and append the current page to the
* list
*/
/* We are somewhere in the middle of the history and a
* new page was visited. Purge all entries from the current index
* till the end of the list and append the current page to the
* list
*/
for(int i=mHistoryLength-1; i>mHistoryCurrentIndex; i--) {
nsHistoryEntry * hEntry2 = (nsHistoryEntry *)mHistoryEntries.ElementAt(i);
//NS_IF_RELEASE(hEntry2);
delete hEntry2;
mHistoryEntries.RemoveElementAt(i);
mHistoryLength--;
}
for(int i=mHistoryLength-1; i>mHistoryCurrentIndex; i--) {
nsHistoryEntry * hEntry2 = (nsHistoryEntry *)mHistoryEntries.ElementAt(i);
//NS_IF_RELEASE(hEntry2);
delete hEntry2;
mHistoryEntries.RemoveElementAt(i);
mHistoryLength--;
}
}
mHistoryEntries.AppendElement((void *)hEntry);
@ -850,7 +950,6 @@ nsSessionHistory::add(nsIWebShell * aWebShell)
} // (!mParent)
else {
/* This is a frame webshell. Check if it is a new frame. If so,
* append to the existing history entry. Else, create a
* new tree to record the change in URL
@ -886,8 +985,8 @@ nsSessionHistory::add(nsIWebShell * aWebShell)
newEntry->Create(aWebShell, parentEntry, this);
aWebShell->SetIsInSHist(PR_TRUE);
if (parentWS)
NS_RELEASE(parentWS);
if (parentWS)
NS_RELEASE(parentWS);
} // !mIsLoadingDoc
else {
@ -912,8 +1011,8 @@ nsSessionHistory::add(nsIWebShell * aWebShell)
mHistoryEntryInLoad = (nsHistoryEntry *)nsnull;
} //!ret
aWebShell->SetIsInSHist(PR_TRUE);
if (root)
NS_RELEASE(root);
if (root)
NS_RELEASE(root);
}
} // !InSHist
else {
@ -950,8 +1049,8 @@ nsSessionHistory::add(nsIWebShell * aWebShell)
mHistoryCurrentIndex++;
return NS_OK;
} //newEntry
if (root)
NS_RELEASE(root);
if (root)
NS_RELEASE(root);
} // (!mIsLoadingDoc)
else {
@ -985,6 +1084,102 @@ nsSessionHistory::add(nsIWebShell * aWebShell)
}
NS_IMETHODIMP
nsSessionHistory::ClearLoadingFlags()
{
mIsLoadingDoc = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsSessionHistory::UpdateStatus(nsIWebShell * aWebShell, nsresult aStatus) {
if (!mIsLoadingDoc) {
if (!NS_SUCCEEDED(aStatus)) {
/* if this was a fresh page load and if it failed,
* remove the entry for in in Session History
*/
nsHistoryEntry * cEntry = (nsHistoryEntry *) mHistoryEntries.ElementAt(mHistoryCurrentIndex);
mHistoryEntries.RemoveElementAt(mHistoryCurrentIndex);
delete cEntry;
mHistoryCurrentIndex--;
mHistoryLength--;
return NS_OK;
}
} // (!mIsLoadingDoc)
else {
/* We are currently in the middle of loading a history entry.
* Not sure if we are done with all the subframes etc...
*/
if (!NS_SUCCEEDED(aStatus)) {
/*
* But if the History page load failed for some reason,
* Clear the loading flags, leave the current index as it is for now.
*/
mIsLoadingDoc= PR_FALSE;
mHistoryEntryInLoad = (nsHistoryEntry *) nsnull;
return NS_OK;
}
nsIWebShell * parent = nsnull;
if (!aWebShell || !mHistoryEntryInLoad) {
return NS_ERROR_NULL_POINTER;
}
aWebShell->GetParent(parent);
if (!parent) {
/* Pass the document to Load() to check if the URLs match.
* Load() will take care of differences in URL
*/
nsresult ret = mHistoryEntryInLoad->Compare(aWebShell, PR_FALSE);
if (!ret) {
/* The URL in the webshell exactly matches with the
* one in history. Clear all flags and return.
*/
mIsLoadingDoc = PR_FALSE;
mHistoryEntryInLoad = (nsHistoryEntry *)nsnull;
}
return NS_OK;
} // (!parent)
else {
/* This is a frame webshell */
PRBool inSHist = PR_TRUE;
aWebShell->GetIsInSHist(inSHist);
if (inSHist) {
/* This page is in history. May be the frame page changed.
* Send it to Load() for Comparison purposes
*/
nsIWebShell * root=nsnull;
aWebShell->GetRootWebShell(root);
if (!root) {
NS_ASSERTION(0,"nsSessionHistory::add Couldn't get root webshell");
return NS_OK;
}
PRBool ret = mHistoryEntryInLoad->Compare(root, PR_FALSE);
if (!ret) {
/* The page in webshell matches exactly with the one in history.
* Clear all flags and return.
*/
mIsLoadingDoc = PR_FALSE;
mHistoryEntryInLoad = (nsHistoryEntry *)nsnull;
} //!ret
if (root)
NS_RELEASE(root);
} //inSHist
} // else for (!parent)
if (parent)
NS_RELEASE(parent);
} // else for (!mIsLoadingDoc)
return NS_OK;
}
NS_IMETHODIMP
nsSessionHistory::Goto(PRInt32 aGotoIndex, nsIWebShell * prev, PRBool aIsReload)
{
@ -1010,6 +1205,7 @@ nsSessionHistory::Goto(PRInt32 aGotoIndex, nsIWebShell * prev, PRBool aIsReload)
nsString urlString(url);
if (APP_DEBUG) printf("nsSessionHistory::Goto, Trying to load URL %s\n", urlString.ToNewCString());
mHistoryCurrentIndex = aGotoIndex;
if (hCurrentEntry != nsnull)
result = hCurrentEntry->Load(prev, aIsReload);
if (!result) {
@ -1017,6 +1213,7 @@ nsSessionHistory::Goto(PRInt32 aGotoIndex, nsIWebShell * prev, PRBool aIsReload)
mHistoryEntryInLoad = (nsHistoryEntry *) nsnull;
}
#if 0
if (aIsReload) {
prev->LoadURL(urlString.GetUnicode(), nsnull, PR_FALSE);
@ -1030,11 +1227,7 @@ nsSessionHistory::Goto(PRInt32 aGotoIndex, nsIWebShell * prev, PRBool aIsReload)
mIsLoadingDoc = PR_FALSE;
mHistoryEntryInLoad = (nsHistoryEntry *) nsnull;
}
#endif /* 0 */
mHistoryCurrentIndex = aGotoIndex;
#endif /* 0 */
return NS_OK;
}

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