diff --git a/mozilla/docshell/base/nsWebShell.cpp b/mozilla/docshell/base/nsWebShell.cpp index 596726ffde0..4863b6c251a 100644 --- a/mozilla/docshell/base/nsWebShell.cpp +++ b/mozilla/docshell/base/nsWebShell.cpp @@ -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 historyState; - - // Get the history object for the previous page. - rv = GetHistoryState(getter_AddRefs(historyState)); - nsCOMPtr rootWebShell; - rv = GetRootWebShell(*getter_AddRefs(rootWebShell)); - if (NS_SUCCEEDED(rv) && rootWebShell) { - nsCOMPtr 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 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 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 root; + nsCOMPtr 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 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 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 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); } } } diff --git a/mozilla/webshell/src/nsWebShell.cpp b/mozilla/webshell/src/nsWebShell.cpp index 596726ffde0..4863b6c251a 100644 --- a/mozilla/webshell/src/nsWebShell.cpp +++ b/mozilla/webshell/src/nsWebShell.cpp @@ -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 historyState; - - // Get the history object for the previous page. - rv = GetHistoryState(getter_AddRefs(historyState)); - nsCOMPtr rootWebShell; - rv = GetRootWebShell(*getter_AddRefs(rootWebShell)); - if (NS_SUCCEEDED(rv) && rootWebShell) { - nsCOMPtr 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 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 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 root; + nsCOMPtr 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 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 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 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); } } } diff --git a/mozilla/xpfe/appshell/public/nsISessionHistory.h b/mozilla/xpfe/appshell/public/nsISessionHistory.h index be0195754a2..1d8bf0aad9d 100644 --- a/mozilla/xpfe/appshell/public/nsISessionHistory.h +++ b/mozilla/xpfe/appshell/public/nsISessionHistory.h @@ -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; }; diff --git a/mozilla/xpfe/appshell/src/nsSessionHistory.cpp b/mozilla/xpfe/appshell/src/nsSessionHistory.cpp index aebb92b3b75..af74871ebc5 100644 --- a/mozilla/xpfe/appshell/src/nsSessionHistory.cpp +++ b/mozilla/xpfe/appshell/src/nsSessionHistory.cpp @@ -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; iGetChildAt(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; iGetChildAt(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; } diff --git a/mozilla/xpfe/browser/src/nsBrowserInstance.cpp b/mozilla/xpfe/browser/src/nsBrowserInstance.cpp index 53127f498c4..ddf8cce5bf8 100644 --- a/mozilla/xpfe/browser/src/nsBrowserInstance.cpp +++ b/mozilla/xpfe/browser/src/nsBrowserInstance.cpp @@ -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) diff --git a/mozilla/xpfe/browser/src/nsBrowserInstance.h b/mozilla/xpfe/browser/src/nsBrowserInstance.h index 7e749addb7e..e4e38646580 100644 --- a/mozilla/xpfe/browser/src/nsBrowserInstance.h +++ b/mozilla/xpfe/browser/src/nsBrowserInstance.h @@ -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 mSearchContext; // at last, something we really own nsInstanceCounter mInstanceCounter; + PRBool mIsLoadingHistory; #ifdef DEBUG_warren PRIntervalTime mLoadStartTime; #endif