diff --git a/docshell/base/nsWebShell.cpp b/docshell/base/nsWebShell.cpp index 6de9527158a..d408b3c2212 100644 --- a/docshell/base/nsWebShell.cpp +++ b/docshell/base/nsWebShell.cpp @@ -195,7 +195,7 @@ nsWebShell::~nsWebShell() #if 0 nsrefcnt refcnt; NS_RELEASE2(mDocLoader, refcnt); - NS_ASSERTION(mDocLoader == nsnull, "Still have a docloader? who owns it?!"); + NS_ASSERTION(refcnt == 0, "Still have a docloader? who owns it?!"); #else NS_RELEASE(mDocLoader); #endif @@ -695,6 +695,65 @@ nsWebShell::OnOverLink(nsIContent* aContent, return rv; } +nsresult +nsWebShell::NormalizeURI(nsACString& aURLSpec) +{ + nsIURI *uri = nsnull; + nsCAutoString scheme; + nsresult rv = mIOService->ExtractScheme(aURLSpec, scheme); + if (NS_FAILED(rv)) return rv; + + // keep tempUri up here to keep it in scope + nsCOMPtr tempUri; + + // used to avoid extra work later + PRBool clearUri(PR_TRUE); + + if (scheme.Equals(NS_LITERAL_CSTRING("http"))) { + if (mCachedHttpUrl) + rv = mCachedHttpUrl->SetSpec(aURLSpec); + else + rv = NS_NewURI(getter_AddRefs(mCachedHttpUrl), aURLSpec); + + uri = mCachedHttpUrl; + } + + else if (scheme.Equals(NS_LITERAL_CSTRING("https"))) { + if (mCachedHttpsUrl) + rv = mCachedHttpsUrl->SetSpec(aURLSpec); + else + rv = NS_NewURI(getter_AddRefs(mCachedHttpsUrl), aURLSpec); + + uri = mCachedHttpsUrl; + } + + else if (scheme.Equals(NS_LITERAL_CSTRING("ftp"))) { + if (mCachedFtpUrl) + rv = mCachedFtpUrl->SetSpec(aURLSpec); + else + rv = NS_NewURI(getter_AddRefs(mCachedFtpUrl), aURLSpec); + + uri = mCachedFtpUrl; + } else { + rv = NS_NewURI(getter_AddRefs(tempUri), aURLSpec); + uri = tempUri; + clearUri = PR_FALSE; + } + + // covers all above failures + if (NS_FAILED(rv)) return rv; + + rv = uri->GetSpec(aURLSpec); + + // clear out the old spec, for security reasons - old data should + // not be floating around in cached URIs! + // (but avoid doing extra work if we're just destroying the uri) + if (clearUri) + uri->SetSpec(NS_LITERAL_CSTRING("")); + + return rv; +} + NS_IMETHODIMP nsWebShell::GetLinkState(const nsACString& aLinkURI, nsLinkState& aState) { @@ -707,24 +766,13 @@ nsWebShell::GetLinkState(const nsACString& aLinkURI, nsLinkState& aState) // default to the given URI nsCAutoString resolvedPath(aLinkURI); nsresult rv; - + // get the cached IO service - if (!mIOService) { + if (!mIOService) mIOService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) { + NormalizeURI(resolvedPath); - // clean up the url using the right parser - nsCOMPtr uri; - rv = NS_NewURI(getter_AddRefs(uri), aLinkURI, nsnull, nsnull, - mIOService); - - // now get the fully canonicalized path - if (NS_SUCCEEDED(rv)) - rv = uri->GetSpec(resolvedPath); - } - } - PRBool isVisited; NS_ENSURE_SUCCESS(mGlobalHistory->IsVisited(resolvedPath.get(), &isVisited), NS_ERROR_FAILURE); diff --git a/docshell/base/nsWebShell.h b/docshell/base/nsWebShell.h index b555af7a8ad..b1988224030 100644 --- a/docshell/base/nsWebShell.h +++ b/docshell/base/nsWebShell.h @@ -115,6 +115,8 @@ protected: nsIChannel* channel, nsresult aStatus); + nsresult NormalizeURI(nsACString& aURLSpec); + PRThread *mThread; nsIWebShellContainer* mContainer; @@ -133,6 +135,14 @@ protected: // cached io service for NS_NewURI nsCOMPtr mIOService; + + // these are specifically cached for these + // protocols, because we're optimizing for link coloring - + // most links are http, https, or ftp + nsCOMPtr mCachedHttpUrl; + nsCOMPtr mCachedHttpsUrl; + nsCOMPtr mCachedFtpUrl; + #ifdef DEBUG private: