mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-04 07:40:42 +00:00
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:
parent
a0d9a79a54
commit
98ab0bb7c2
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user