NS_IMETHODIMP nsLocation::Replace(const nsAString& aUrl) { nsresult rv = NS_OK; // Get JSContext from stack. nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1")); if (stack) { JSContext *cx; rv = GetContextFromStack(stack, &cx); NS_ENSURE_SUCCESS(rv, rv); if (cx) { return SetHrefWithContext(cx, aUrl, PR_TRUE); } } nsAutoString oldHref; rv = GetHref(oldHref); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIURI> oldUri; rv = NS_NewURI(getter_AddRefs(oldUri), oldHref); NS_ENSURE_SUCCESS(rv, rv); return SetHrefWithBase(aUrl, oldUri, PR_TRUE); }
NS_IMETHODIMP Location::SetHref(const nsAString& aHref) { nsAutoString oldHref; nsresult rv = NS_OK; JSContext *cx = nsContentUtils::GetCurrentJSContext(); if (cx) { rv = SetHrefWithContext(cx, aHref, false); } else { rv = GetHref(oldHref); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIURI> oldUri; rv = NS_NewURI(getter_AddRefs(oldUri), oldHref); if (oldUri) { rv = SetHrefWithBase(aHref, oldUri, false); } } } return rv; }
void Location::Assign(const nsAString& aUrl, nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) { if (!CallerSubsumes(&aSubjectPrincipal)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) { aRv = SetHrefWithContext(cx, aUrl, false); return; } nsAutoString oldHref; aRv = GetHref(oldHref); if (NS_WARN_IF(aRv.Failed())) { return; } nsCOMPtr<nsIURI> oldUri; aRv = NS_NewURI(getter_AddRefs(oldUri), oldHref); if (NS_WARN_IF(aRv.Failed())) { return; } if (oldUri) { aRv = SetHrefWithBase(aUrl, oldUri, false); } }
void Location::Replace(const nsAString& aUrl, nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) { if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) { aRv = SetHrefWithContext(cx, aUrl, true); return; } nsAutoString oldHref; aRv = GetHref(oldHref); if (NS_WARN_IF(aRv.Failed())) { return; } nsCOMPtr<nsIURI> oldUri; aRv = NS_NewURI(getter_AddRefs(oldUri), oldHref); if (NS_WARN_IF(aRv.Failed())) { return; } aRv = SetHrefWithBase(aUrl, oldUri, true); }
void Location::SetHref(const nsAString& aHref, ErrorResult& aRv) { JSContext *cx = nsContentUtils::GetCurrentJSContext(); if (cx) { aRv = SetHrefWithContext(cx, aHref, false); return; } nsAutoString oldHref; aRv = GetHref(oldHref); if (NS_WARN_IF(aRv.Failed())) { return; } nsCOMPtr<nsIURI> oldUri; aRv = NS_NewURI(getter_AddRefs(oldUri), oldHref); if (NS_WARN_IF(aRv.Failed())) { return; } aRv = SetHrefWithBase(aHref, oldUri, false); if (NS_WARN_IF(aRv.Failed())) { return; } }
nsresult Location::SetHrefWithContext(JSContext* cx, const nsAString& aHref, bool aReplace) { nsCOMPtr<nsIURI> base; // Get the source of the caller nsresult result = GetSourceBaseURL(cx, getter_AddRefs(base)); if (NS_FAILED(result)) { return result; } return SetHrefWithBase(aHref, base, aReplace); }
NS_IMETHODIMP Location::Replace(const nsAString& aUrl) { nsresult rv = NS_OK; if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) { return SetHrefWithContext(cx, aUrl, true); } nsAutoString oldHref; rv = GetHref(oldHref); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIURI> oldUri; rv = NS_NewURI(getter_AddRefs(oldUri), oldHref); NS_ENSURE_SUCCESS(rv, rv); return SetHrefWithBase(aUrl, oldUri, true); }
NS_IMETHODIMP nsLocation::Assign(const nsAString& aUrl) { nsAutoString oldHref; nsresult result = NS_OK; result = GetHref(oldHref); if (NS_SUCCEEDED(result)) { nsCOMPtr<nsIURI> oldUri; result = NS_NewURI(getter_AddRefs(oldUri), oldHref); if (oldUri) { result = SetHrefWithBase(aUrl, oldUri, PR_FALSE); } } return result; }
NS_IMETHODIMP nsLocation::Assign(const nsAString& aUrl) { if (!CallerSubsumes()) return NS_ERROR_DOM_SECURITY_ERR; nsAutoString oldHref; nsresult result = NS_OK; result = GetHref(oldHref); if (NS_SUCCEEDED(result)) { nsCOMPtr<nsIURI> oldUri; result = NS_NewURI(getter_AddRefs(oldUri), oldHref); if (oldUri) { result = SetHrefWithBase(aUrl, oldUri, false); } } return result; }
NS_IMETHODIMP Location::Assign(const nsAString& aUrl) { if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) { return SetHrefWithContext(cx, aUrl, false); } nsAutoString oldHref; nsresult result = NS_OK; result = GetHref(oldHref); if (NS_SUCCEEDED(result)) { nsCOMPtr<nsIURI> oldUri; result = NS_NewURI(getter_AddRefs(oldUri), oldHref); if (oldUri) { result = SetHrefWithBase(aUrl, oldUri, false); } } return result; }
NS_IMETHODIMP nsLocation::SetHref(const nsAString& aHref) { nsAutoString oldHref; nsresult rv = NS_OK; // Get JSContext from stack. nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv)); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; JSContext *cx; if (NS_FAILED(GetContextFromStack(stack, &cx))) return NS_ERROR_FAILURE; if (cx) { rv = SetHrefWithContext(cx, aHref, PR_FALSE); } else { rv = GetHref(oldHref); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIURI> oldUri; rv = NS_NewURI(getter_AddRefs(oldUri), oldHref); if (oldUri) { rv = SetHrefWithBase(aHref, oldUri, PR_FALSE); } } } return rv; }
NS_IMETHODIMP nsLocation::SetHref(const nsAString& aHref) { nsAutoString oldHref; nsresult rv = NS_OK; JSContext *cx = nsContentUtils::GetCurrentJSContext(); // According to HTML5 spec, |location.href = ...| must act as if // it were |location.replace(...)| before the page load finishes. // // http://www.w3.org/TR/2011/WD-html5-20110113/history.html#location // // > The href attribute must return the current address of the // > associated Document object, as an absolute URL. // > // > On setting, if the Location object's associated Document // > object has completely loaded, then the user agent must act // > as if the assign() method had been called with the new value // > as its argument. Otherwise, the user agent must act as if // > the replace() method had been called with the new value as its // > argument. // // Note: The spec says the condition is "Document object has completely // loaded", but that may break some websites. If the user was // willing to move from one page to another, and was able to do // so, we should not overwrite the session history entry even // if the loading has not finished yet. // // https://www.w3.org/Bugs/Public/show_bug.cgi?id=17041 // // See bug 39938, bug 72197, bug 178729 and bug 754029. // About other browsers: // http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2010-July/027372.html bool replace = false; if (!nsEventStateManager::IsHandlingUserInput()) { // "completely loaded" is defined at: // // http://www.w3.org/TR/2012/WD-html5-20120329/the-end.html#completely-loaded // // > 7. document readiness to "complete", and fire "load". // > // > 8. "pageshow" // > // > 9. ApplicationCache // > // > 10. Print in the pending list. // > // > 12. Queue a task to mark the Document as completely loaded. // // Since Gecko doesn't (yet) have a flag corresponding to no. "12. // ... completely loaded", here the logic is a little tricky. nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell)); nsCOMPtr<nsIDocument> document(do_GetInterface(docShell)); if (document) { replace = nsIDocument::READYSTATE_COMPLETE != document->GetReadyStateEnum(); // nsIDocShell::isExecutingOnLoadHandler is true while // the document is handling "load", "pageshow", // "readystatechange" for "complete" and "beforeprint"/"afterprint". // // Maybe this API property needs a better name. if (!replace) { docShell->GetIsExecutingOnLoadHandler(&replace); } } } if (cx) { rv = SetHrefWithContext(cx, aHref, replace); } else { rv = GetHref(oldHref); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIURI> oldUri; rv = NS_NewURI(getter_AddRefs(oldUri), oldHref); if (oldUri) { rv = SetHrefWithBase(aHref, oldUri, replace); } } } return rv; }