Bug 225910 - Use nsIURI's GetRef and GetHasRef in nsDocShell. r=bz

--HG--
extra : rebase_source : 46d7974884b96bd55add4a6c24e2a2ccb8570b4c
This commit is contained in:
Dragana Damjanovic dd.mozilla@gmail.com 2016-04-01 03:37:00 +02:00
Родитель 70b08fa38a
Коммит e69b13996a
5 изменённых файлов: 53 добавлений и 73 удалений

Просмотреть файл

@ -9979,31 +9979,44 @@ nsDocShell::InternalLoad(nsIURI* aURI,
aLoadType == LOAD_HISTORY ||
aLoadType == LOAD_LINK) {
nsCOMPtr<nsIURI> currentURI = mCurrentURI;
// Split currentURI and aURI on the '#' character. Make sure we read
// the return values of SplitURIAtHash; if it fails, we don't want to
// allow a short-circuited navigation.
nsAutoCString curBeforeHash, curHash, newBeforeHash, newHash;
nsresult splitRv1, splitRv2;
splitRv1 = currentURI ?
nsContentUtils::SplitURIAtHash(currentURI, curBeforeHash, curHash) :
NS_ERROR_FAILURE;
splitRv2 = nsContentUtils::SplitURIAtHash(aURI, newBeforeHash, newHash);
bool sameExceptHashes = NS_SUCCEEDED(splitRv1) &&
NS_SUCCEEDED(splitRv2) &&
curBeforeHash.Equals(newBeforeHash);
nsAutoCString curHash, newHash;
bool curURIHasRef = false, newURIHasRef = false;
nsresult rvURINew = aURI->GetRef(newHash);
if (NS_SUCCEEDED(rvURINew)) {
rvURINew = aURI->GetHasRef(&newURIHasRef);
}
bool sameExceptHashes = false;
if (currentURI && NS_SUCCEEDED(rvURINew)) {
nsresult rvURIOld = currentURI->GetRef(curHash);
if (NS_SUCCEEDED(rvURIOld)) {
rvURIOld = currentURI->GetHasRef(&curURIHasRef);
}
if (NS_SUCCEEDED(rvURIOld)) {
if (NS_FAILED(currentURI->EqualsExceptRef(aURI, &sameExceptHashes))) {
sameExceptHashes = false;
}
}
}
if (!sameExceptHashes && sURIFixup && currentURI &&
NS_SUCCEEDED(splitRv2)) {
NS_SUCCEEDED(rvURINew)) {
// Maybe aURI came from the exposable form of currentURI?
nsCOMPtr<nsIURI> currentExposableURI;
rv = sURIFixup->CreateExposableURI(currentURI,
getter_AddRefs(currentExposableURI));
NS_ENSURE_SUCCESS(rv, rv);
splitRv1 = nsContentUtils::SplitURIAtHash(currentExposableURI,
curBeforeHash, curHash);
sameExceptHashes =
NS_SUCCEEDED(splitRv1) && curBeforeHash.Equals(newBeforeHash);
nsresult rvURIOld = currentExposableURI->GetRef(curHash);
if (NS_SUCCEEDED(rvURIOld)) {
rvURIOld = currentExposableURI->GetHasRef(&curURIHasRef);
}
if (NS_SUCCEEDED(rvURIOld)) {
if (NS_FAILED(currentExposableURI->EqualsExceptRef(aURI, &sameExceptHashes))) {
sameExceptHashes = false;
}
}
}
bool historyNavBetweenSameDoc = false;
@ -10039,7 +10052,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
bool doShortCircuitedLoad =
(historyNavBetweenSameDoc && mOSHE != aSHEntry) ||
(!aSHEntry && !aPostData &&
sameExceptHashes && !newHash.IsEmpty());
sameExceptHashes && newURIHasRef);
if (doShortCircuitedLoad) {
// Save the position of the scrollers.
@ -10194,7 +10207,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
// arguments it receives. But even if we don't end up scrolling,
// ScrollToAnchor performs other important tasks, such as informing
// the presShell that we have a new hash. See bug 680257.
rv = ScrollToAnchor(curHash, newHash, aLoadType);
rv = ScrollToAnchor(curURIHasRef, newURIHasRef, newHash, aLoadType);
NS_ENSURE_SUCCESS(rv, rv);
/* restore previous position of scroller(s), if we're moving
@ -10217,7 +10230,8 @@ nsDocShell::InternalLoad(nsIURI* aURI,
// reference to avoid null derefs. See bug 914521.
if (win) {
// Fire a hashchange event URIs differ, and only in their hashes.
bool doHashchange = sameExceptHashes && !curHash.Equals(newHash);
bool doHashchange = sameExceptHashes &&
(curURIHasRef != newURIHasRef || !curHash.Equals(newHash));
if (historyNavBetweenSameDoc || doHashchange) {
win->DispatchSyncPopState();
@ -11127,8 +11141,8 @@ nsDocShell::DoChannelLoad(nsIChannel* aChannel,
}
nsresult
nsDocShell::ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash,
uint32_t aLoadType)
nsDocShell::ScrollToAnchor(bool aCurHasRef, bool aNewHasRef,
nsACString& aNewHash, uint32_t aLoadType)
{
if (!mCurrentURI) {
return NS_OK;
@ -11150,25 +11164,20 @@ nsDocShell::ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash,
// current anchor and we are doing a history load. So return if we have no
// new anchor, and there is no current anchor or the load is not a history
// load.
if ((aCurHash.IsEmpty() || aLoadType != LOAD_HISTORY) &&
aNewHash.IsEmpty()) {
if ((!aCurHasRef || aLoadType != LOAD_HISTORY) && !aNewHasRef) {
return NS_OK;
}
// Take the '#' off aNewHash to get the ref name. (aNewHash might be empty,
// but that's fine.)
nsDependentCSubstring newHashName(aNewHash, 1);
// Both the new and current URIs refer to the same page. We can now
// browse to the hash stored in the new URI.
if (!newHashName.IsEmpty()) {
if (!aNewHash.IsEmpty()) {
// anchor is there, but if it's a load from history,
// we don't have any anchor jumping to do
bool scroll = aLoadType != LOAD_HISTORY &&
aLoadType != LOAD_RELOAD_NORMAL;
char* str = ToNewCString(newHashName);
char* str = ToNewCString(aNewHash);
if (!str) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -11210,7 +11219,7 @@ nsDocShell::ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash,
nsXPIDLString uStr;
rv = textToSubURI->UnEscapeAndConvert(PromiseFlatCString(aCharset).get(),
PromiseFlatCString(newHashName).get(),
PromiseFlatCString(aNewHash).get(),
getter_Copies(uStr));
NS_ENSURE_SUCCESS(rv, rv);
@ -11220,7 +11229,7 @@ nsDocShell::ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash,
// with the new URI no matter whether we actually scrolled
// somewhere).
//
// When newHashName contains "%00", unescaped string may be empty.
// When aNewHash contains "%00", unescaped string may be empty.
// And GoToAnchor asserts if we ask it to scroll to an empty ref.
shell->GoToAnchor(uStr, scroll && !uStr.IsEmpty(),
nsIPresShell::SCROLL_SMOOTH_AUTO);

Просмотреть файл

@ -381,7 +381,9 @@ protected:
nsIURILoader* aURILoader,
bool aBypassClassifier);
nsresult ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash,
nsresult ScrollToAnchor(bool aCurHasRef,
bool aNewHasRef,
nsACString& aNewHash,
uint32_t aLoadType);
// Returns true if would have called FireOnLocationChange,

Просмотреть файл

@ -5421,32 +5421,6 @@ nsContentUtils::URIIsLocalFile(nsIURI *aURI)
isFile;
}
nsresult
nsContentUtils::SplitURIAtHash(nsIURI *aURI,
nsACString &aBeforeHash,
nsACString &aAfterHash)
{
// See bug 225910 for why we can't do this using nsIURL.
aBeforeHash.Truncate();
aAfterHash.Truncate();
NS_ENSURE_ARG_POINTER(aURI);
nsAutoCString spec;
nsresult rv = aURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
int32_t index = spec.FindChar('#');
if (index == -1) {
index = spec.Length();
}
aBeforeHash.Assign(Substring(spec, 0, index));
aAfterHash.Assign(Substring(spec, index));
return NS_OK;
}
/* static */
nsIScriptContext*
nsContentUtils::GetContextForEventHandlers(nsINode* aNode,

Просмотреть файл

@ -1551,14 +1551,6 @@ public:
*/
static bool URIIsLocalFile(nsIURI *aURI);
/**
* Given a URI, return set beforeHash to the part before the '#', and
* afterHash to the remainder of the URI, including the '#'.
*/
static nsresult SplitURIAtHash(nsIURI *aURI,
nsACString &aBeforeHash,
nsACString &aAfterHash);
/**
* Get the application manifest URI for this document. The manifest URI
* is specified in the manifest= attribute of the root element of the

Просмотреть файл

@ -9874,12 +9874,15 @@ nsGlobalWindow::DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI)
// Make sure that aOldURI and aNewURI are identical up to the '#', and that
// their hashes are different.
nsAutoCString oldBeforeHash, oldHash, newBeforeHash, newHash;
nsContentUtils::SplitURIAtHash(aOldURI, oldBeforeHash, oldHash);
nsContentUtils::SplitURIAtHash(aNewURI, newBeforeHash, newHash);
NS_ENSURE_STATE(oldBeforeHash.Equals(newBeforeHash));
NS_ENSURE_STATE(!oldHash.Equals(newHash));
bool equal = false;
NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->EqualsExceptRef(aNewURI, &equal)) && equal);
nsAutoCString oldHash, newHash;
bool oldHasHash, newHasHash;
NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->GetRef(oldHash)) &&
NS_SUCCEEDED(aNewURI->GetRef(newHash)) &&
NS_SUCCEEDED(aOldURI->GetHasRef(&oldHasHash)) &&
NS_SUCCEEDED(aNewURI->GetHasRef(&newHasHash)) &&
(oldHasHash != newHasHash || !oldHash.Equals(newHash)));
nsAutoCString oldSpec, newSpec;
aOldURI->GetSpec(oldSpec);