Bug 1962710 - Part 3: Fire NavigateEvent for regular navigations. r=smaug,necko-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D249242
This commit is contained in:
committed by
afarre@mozilla.com
parent
d2e41c93c1
commit
e10114d313
@@ -7,6 +7,7 @@
|
|||||||
#include "nsDocShell.h"
|
#include "nsDocShell.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "mozilla/dom/HTMLFormElement.h"
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
# include <process.h>
|
# include <process.h>
|
||||||
@@ -3930,7 +3931,7 @@ nsresult nsDocShell::ReloadNavigable(
|
|||||||
if (!navigation->FirePushReplaceReloadNavigateEvent(
|
if (!navigation->FirePushReplaceReloadNavigateEvent(
|
||||||
aCx, NavigationType::Reload, destinationURL,
|
aCx, NavigationType::Reload, destinationURL,
|
||||||
/* aIsSameDocument */ false, Some(aUserInvolvement),
|
/* aIsSameDocument */ false, Some(aUserInvolvement),
|
||||||
/* aSourceElement*/ nullptr, /* aFormDataEntryList */ Nothing{},
|
/* aSourceElement*/ nullptr, /* aFormDataEntryList */ nullptr,
|
||||||
destinationNavigationAPIState,
|
destinationNavigationAPIState,
|
||||||
/* aClassiCHistoryAPIState */ nullptr)) {
|
/* aClassiCHistoryAPIState */ nullptr)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@@ -8772,7 +8773,7 @@ nsresult nsDocShell::HandleSameDocumentNavigation(
|
|||||||
jsapi.cx(), aLoadState->GetNavigationType(), newURI,
|
jsapi.cx(), aLoadState->GetNavigationType(), newURI,
|
||||||
/* aIsSameDocument */ true,
|
/* aIsSameDocument */ true,
|
||||||
Some(aLoadState->UserNavigationInvolvement()), sourceElement,
|
Some(aLoadState->UserNavigationInvolvement()), sourceElement,
|
||||||
/* aFormDataEntryList */ Nothing(),
|
/* aFormDataEntryList */ nullptr,
|
||||||
/* aNavigationAPIState */ destinationNavigationAPIState,
|
/* aNavigationAPIState */ destinationNavigationAPIState,
|
||||||
/* aClassicHistoryAPIState */ nullptr);
|
/* aClassicHistoryAPIState */ nullptr);
|
||||||
|
|
||||||
@@ -9276,6 +9277,8 @@ uint32_t nsDocShell::GetLoadTypeForFormSubmission(
|
|||||||
: LOAD_LINK;
|
: LOAD_LINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InternalLoad performs several of the steps from
|
||||||
|
// https://html.spec.whatwg.org/#navigate.
|
||||||
nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
|
nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
|
||||||
Maybe<uint32_t> aCacheKey) {
|
Maybe<uint32_t> aCacheKey) {
|
||||||
MOZ_ASSERT(aLoadState, "need a load state!");
|
MOZ_ASSERT(aLoadState, "need a load state!");
|
||||||
@@ -9485,6 +9488,52 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
|
|||||||
if (mTiming && !isDownload) {
|
if (mTiming && !isDownload) {
|
||||||
mTiming->NotifyBeforeUnload();
|
mTiming->NotifyBeforeUnload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following steps are from https://html.spec.whatwg.org/#navigate
|
||||||
|
// Step 20
|
||||||
|
if (RefPtr<Document> document = GetDocument();
|
||||||
|
document &&
|
||||||
|
aLoadState->UserNavigationInvolvement() !=
|
||||||
|
UserNavigationInvolvement::BrowserUI &&
|
||||||
|
!document->IsInitialDocument() &&
|
||||||
|
!NS_IsAboutBlankAllowQueryAndFragment(document->GetDocumentURI()) &&
|
||||||
|
NS_IsFetchScheme(aLoadState->URI()) &&
|
||||||
|
document->NodePrincipal()->Subsumes(aLoadState->TriggeringPrincipal())) {
|
||||||
|
if (nsCOMPtr<nsPIDOMWindowInner> window = document->GetInnerWindow()) {
|
||||||
|
// Step 20.1
|
||||||
|
if (RefPtr<Navigation> navigation = window->Navigation()) {
|
||||||
|
AutoJSAPI jsapi;
|
||||||
|
if (jsapi.Init(window)) {
|
||||||
|
RefPtr<Element> sourceElement = aLoadState->GetSourceElement();
|
||||||
|
|
||||||
|
// Step 20.2
|
||||||
|
RefPtr<FormData> formData = aLoadState->GetFormDataEntryList();
|
||||||
|
|
||||||
|
// Step 20.3
|
||||||
|
RefPtr<nsIStructuredCloneContainer> navigationAPIStateForFiring =
|
||||||
|
aLoadState->GetNavigationAPIState();
|
||||||
|
if (!navigationAPIStateForFiring) {
|
||||||
|
navigationAPIStateForFiring = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> destinationURL = aLoadState->URI();
|
||||||
|
// Step 20.4
|
||||||
|
bool shouldContinue = navigation->FirePushReplaceReloadNavigateEvent(
|
||||||
|
jsapi.cx(), aLoadState->GetNavigationType(), destinationURL,
|
||||||
|
/* aIsSameDocument */ false,
|
||||||
|
Some(aLoadState->UserNavigationInvolvement()), sourceElement,
|
||||||
|
formData.forget(), navigationAPIStateForFiring,
|
||||||
|
/* aClassicHistoryAPIState */ nullptr);
|
||||||
|
|
||||||
|
// Step 20.5
|
||||||
|
if (!shouldContinue) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the page doesn't want to be unloaded. The javascript:
|
// Check if the page doesn't want to be unloaded. The javascript:
|
||||||
// protocol handler deals with this for javascript: URLs.
|
// protocol handler deals with this for javascript: URLs.
|
||||||
// NOTE(emilio): As of this writing, other browsers fire beforeunload for
|
// NOTE(emilio): As of this writing, other browsers fire beforeunload for
|
||||||
@@ -11450,7 +11499,7 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
|||||||
aCx, aReplace ? NavigationType::Replace : NavigationType::Push,
|
aCx, aReplace ? NavigationType::Replace : NavigationType::Push,
|
||||||
newURI,
|
newURI,
|
||||||
/* aIsSameDocument */ true, /* aUserInvolvement */ Nothing(),
|
/* aIsSameDocument */ true, /* aUserInvolvement */ Nothing(),
|
||||||
/* aSourceElement */ nullptr, /* aFormDataEntryList */ Nothing(),
|
/* aSourceElement */ nullptr, /* aFormDataEntryList */ nullptr,
|
||||||
/* aNavigationAPIState */ nullptr, scContainer);
|
/* aNavigationAPIState */ nullptr, scContainer);
|
||||||
|
|
||||||
// Step 9
|
// Step 9
|
||||||
@@ -13265,6 +13314,7 @@ nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent,
|
|||||||
aLoadState->SetTypeHint(NS_ConvertUTF16toUTF8(typeHint));
|
aLoadState->SetTypeHint(NS_ConvertUTF16toUTF8(typeHint));
|
||||||
aLoadState->SetLoadType(loadType);
|
aLoadState->SetLoadType(loadType);
|
||||||
aLoadState->SetSourceBrowsingContext(mBrowsingContext);
|
aLoadState->SetSourceBrowsingContext(mBrowsingContext);
|
||||||
|
aLoadState->SetSourceElement(aContent->AsElement());
|
||||||
|
|
||||||
nsresult rv = InternalLoad(aLoadState);
|
nsresult rv = InternalLoad(aLoadState);
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "mozilla/dom/BrowsingContext.h"
|
#include "mozilla/dom/BrowsingContext.h"
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
|
#include "mozilla/dom/FormData.h"
|
||||||
#include "mozilla/dom/LoadURIOptionsBinding.h"
|
#include "mozilla/dom/LoadURIOptionsBinding.h"
|
||||||
#include "mozilla/dom/nsHTTPSOnlyUtils.h"
|
#include "mozilla/dom/nsHTTPSOnlyUtils.h"
|
||||||
#include "mozilla/StaticPrefs_browser.h"
|
#include "mozilla/StaticPrefs_browser.h"
|
||||||
@@ -755,20 +756,6 @@ bool nsDocShellLoadState::LoadIsFromSessionHistory() const {
|
|||||||
: !!mSHEntry;
|
: !!mSHEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIStructuredCloneContainer* nsDocShellLoadState::GetNavigationAPIState()
|
|
||||||
const {
|
|
||||||
return mNavigationAPIState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsDocShellLoadState::SetNavigationAPIState(
|
|
||||||
nsIStructuredCloneContainer* aNavigationAPIState) {
|
|
||||||
mNavigationAPIState = aNavigationAPIState;
|
|
||||||
}
|
|
||||||
|
|
||||||
NavigationType nsDocShellLoadState::GetNavigationType() const {
|
|
||||||
return LoadReplace() ? NavigationType::Replace : NavigationType::Push;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsDocShellLoadState::MaybeStripTrackerQueryStrings(
|
void nsDocShellLoadState::MaybeStripTrackerQueryStrings(
|
||||||
BrowsingContext* aContext) {
|
BrowsingContext* aContext) {
|
||||||
MOZ_ASSERT(aContext);
|
MOZ_ASSERT(aContext);
|
||||||
@@ -1424,3 +1411,26 @@ already_AddRefed<Element> nsDocShellLoadState::GetSourceElement() const {
|
|||||||
nsCOMPtr<Element> element = do_QueryReferent(mSourceElement);
|
nsCOMPtr<Element> element = do_QueryReferent(mSourceElement);
|
||||||
return element.forget();
|
return element.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsIStructuredCloneContainer* nsDocShellLoadState::GetNavigationAPIState()
|
||||||
|
const {
|
||||||
|
return mNavigationAPIState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDocShellLoadState::SetNavigationAPIState(
|
||||||
|
nsIStructuredCloneContainer* aNavigationAPIState) {
|
||||||
|
mNavigationAPIState = aNavigationAPIState;
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationType nsDocShellLoadState::GetNavigationType() const {
|
||||||
|
return LoadReplace() ? NavigationType::Replace : NavigationType::Push;
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::dom::FormData* nsDocShellLoadState::GetFormDataEntryList() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDocShellLoadState::SetFormDataEntryList(
|
||||||
|
mozilla::dom::FormData* aFormDataEntryList) {
|
||||||
|
mFormDataEntryList = aFormDataEntryList;
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class OriginAttributes;
|
|||||||
template <typename, class>
|
template <typename, class>
|
||||||
class UniquePtr;
|
class UniquePtr;
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
class FormData;
|
||||||
class DocShellLoadStateInit;
|
class DocShellLoadStateInit;
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
@@ -196,14 +197,6 @@ class nsDocShellLoadState final {
|
|||||||
|
|
||||||
bool LoadIsFromSessionHistory() const;
|
bool LoadIsFromSessionHistory() const;
|
||||||
|
|
||||||
nsIStructuredCloneContainer* GetNavigationAPIState() const;
|
|
||||||
|
|
||||||
// This is used as the parameter for https://html.spec.whatwg.org/#navigate,
|
|
||||||
// but it's currently missing. See bug 1966674
|
|
||||||
void SetNavigationAPIState(nsIStructuredCloneContainer* aNavigationAPIState);
|
|
||||||
|
|
||||||
mozilla::dom::NavigationType GetNavigationType() const;
|
|
||||||
|
|
||||||
const nsString& Target() const;
|
const nsString& Target() const;
|
||||||
|
|
||||||
void SetTarget(const nsAString& aTarget);
|
void SetTarget(const nsAString& aTarget);
|
||||||
@@ -417,9 +410,23 @@ class nsDocShellLoadState final {
|
|||||||
|
|
||||||
void MaybeStripTrackerQueryStrings(mozilla::dom::BrowsingContext* aContext);
|
void MaybeStripTrackerQueryStrings(mozilla::dom::BrowsingContext* aContext);
|
||||||
|
|
||||||
|
// This is used as the parameter for https://html.spec.whatwg.org/#navigate
|
||||||
void SetSourceElement(mozilla::dom::Element* aElement);
|
void SetSourceElement(mozilla::dom::Element* aElement);
|
||||||
already_AddRefed<mozilla::dom::Element> GetSourceElement() const;
|
already_AddRefed<mozilla::dom::Element> GetSourceElement() const;
|
||||||
|
|
||||||
|
// This is used as the parameter for https://html.spec.whatwg.org/#navigate,
|
||||||
|
// but it's currently missing. See bug 1966674
|
||||||
|
nsIStructuredCloneContainer* GetNavigationAPIState() const;
|
||||||
|
void SetNavigationAPIState(nsIStructuredCloneContainer* aNavigationAPIState);
|
||||||
|
|
||||||
|
// This is used as the parameter for https://html.spec.whatwg.org/#navigate
|
||||||
|
mozilla::dom::NavigationType GetNavigationType() const;
|
||||||
|
|
||||||
|
// This is used as the parameter for https://html.spec.whatwg.org/#navigate
|
||||||
|
// It should only ever be set if the method is POST.
|
||||||
|
mozilla::dom::FormData* GetFormDataEntryList();
|
||||||
|
void SetFormDataEntryList(mozilla::dom::FormData* aFormDataEntryList);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Destructor can't be defaulted or inlined, as header doesn't have all type
|
// Destructor can't be defaulted or inlined, as header doesn't have all type
|
||||||
// includes it needs to do so.
|
// includes it needs to do so.
|
||||||
@@ -561,8 +568,6 @@ class nsDocShellLoadState final {
|
|||||||
mozilla::UniquePtr<mozilla::dom::LoadingSessionHistoryInfo>
|
mozilla::UniquePtr<mozilla::dom::LoadingSessionHistoryInfo>
|
||||||
mLoadingSessionHistoryInfo;
|
mLoadingSessionHistoryInfo;
|
||||||
|
|
||||||
nsCOMPtr<nsIStructuredCloneContainer> mNavigationAPIState;
|
|
||||||
|
|
||||||
// Target for load, like _content, _blank etc.
|
// Target for load, like _content, _blank etc.
|
||||||
nsString mTarget;
|
nsString mTarget;
|
||||||
|
|
||||||
@@ -674,6 +679,10 @@ class nsDocShellLoadState final {
|
|||||||
nsILoadInfo::NOT_INITIALIZED;
|
nsILoadInfo::NOT_INITIALIZED;
|
||||||
|
|
||||||
nsWeakPtr mSourceElement;
|
nsWeakPtr mSourceElement;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIStructuredCloneContainer> mNavigationAPIState;
|
||||||
|
|
||||||
|
RefPtr<mozilla::dom::FormData> mFormDataEntryList;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsDocShellLoadState_h__ */
|
#endif /* nsDocShellLoadState_h__ */
|
||||||
|
|||||||
@@ -307,9 +307,18 @@ already_AddRefed<FormData> FormData::Constructor(
|
|||||||
const GlobalObject& aGlobal,
|
const GlobalObject& aGlobal,
|
||||||
const Optional<NonNull<HTMLFormElement> >& aFormElement,
|
const Optional<NonNull<HTMLFormElement> >& aFormElement,
|
||||||
nsGenericHTMLElement* aSubmitter, ErrorResult& aRv) {
|
nsGenericHTMLElement* aSubmitter, ErrorResult& aRv) {
|
||||||
|
return Constructor(aGlobal.GetAsSupports(),
|
||||||
|
aFormElement.WasPassed() ? &aFormElement.Value() : nullptr,
|
||||||
|
aSubmitter, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
already_AddRefed<FormData> FormData::Constructor(
|
||||||
|
nsISupports* aGlobal, HTMLFormElement* aFormElement,
|
||||||
|
nsGenericHTMLElement* aSubmitter, ErrorResult& aRv) {
|
||||||
RefPtr<FormData> formData;
|
RefPtr<FormData> formData;
|
||||||
// 1. If form is given, then:
|
// 1. If form is given, then:
|
||||||
if (aFormElement.WasPassed()) {
|
if (aFormElement) {
|
||||||
// 1.1. If submitter is non-null, then:
|
// 1.1. If submitter is non-null, then:
|
||||||
if (aSubmitter) {
|
if (aSubmitter) {
|
||||||
const nsIFormControl* fc = nsIFormControl::FromNode(aSubmitter);
|
const nsIFormControl* fc = nsIFormControl::FromNode(aSubmitter);
|
||||||
@@ -322,7 +331,7 @@ already_AddRefed<FormData> FormData::Constructor(
|
|||||||
|
|
||||||
// 1.1.2. If submitter's form owner is not this form element, then throw a
|
// 1.1.2. If submitter's form owner is not this form element, then throw a
|
||||||
// "NotFoundError" DOMException.
|
// "NotFoundError" DOMException.
|
||||||
if (fc->GetForm() != &aFormElement.Value()) {
|
if (fc->GetForm() != aFormElement) {
|
||||||
aRv.ThrowNotFoundError("The submitter is not owned by this form.");
|
aRv.ThrowNotFoundError("The submitter is not owned by this form.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -330,9 +339,8 @@ already_AddRefed<FormData> FormData::Constructor(
|
|||||||
|
|
||||||
// 1.2. Let list be the result of constructing the entry list for form and
|
// 1.2. Let list be the result of constructing the entry list for form and
|
||||||
// submitter.
|
// submitter.
|
||||||
formData =
|
formData = new FormData(aGlobal, UTF_8_ENCODING, aSubmitter);
|
||||||
new FormData(aGlobal.GetAsSupports(), UTF_8_ENCODING, aSubmitter);
|
aRv = aFormElement->ConstructEntryList(formData);
|
||||||
aRv = aFormElement.Value().ConstructEntryList(formData);
|
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -341,7 +349,7 @@ already_AddRefed<FormData> FormData::Constructor(
|
|||||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-form-data-set
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-form-data-set
|
||||||
formData = formData->Clone();
|
formData = formData->Clone();
|
||||||
} else {
|
} else {
|
||||||
formData = new FormData(aGlobal.GetAsSupports());
|
formData = new FormData(aGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return formData.forget();
|
return formData.forget();
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ class FormData final : public nsISupports,
|
|||||||
const Optional<NonNull<HTMLFormElement> >& aFormElement,
|
const Optional<NonNull<HTMLFormElement> >& aFormElement,
|
||||||
nsGenericHTMLElement* aSubmitter, ErrorResult& aRv);
|
nsGenericHTMLElement* aSubmitter, ErrorResult& aRv);
|
||||||
|
|
||||||
|
static already_AddRefed<FormData> Constructor(
|
||||||
|
nsISupports* aGlobal, HTMLFormElement* aFormElement,
|
||||||
|
nsGenericHTMLElement* aSubmitter, ErrorResult& aRv);
|
||||||
|
|
||||||
void Append(const nsAString& aName, const nsAString& aValue,
|
void Append(const nsAString& aName, const nsAString& aValue,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
|||||||
@@ -784,7 +784,7 @@ nsresult HTMLFormElement::BuildSubmission(HTMLFormSubmission** aFormSubmission,
|
|||||||
//
|
//
|
||||||
// Get the submission object
|
// Get the submission object
|
||||||
//
|
//
|
||||||
rv = HTMLFormSubmission::GetFromForm(this, submitter, encoding,
|
rv = HTMLFormSubmission::GetFromForm(this, submitter, encoding, formData,
|
||||||
aFormSubmission);
|
aFormSubmission);
|
||||||
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
||||||
|
|
||||||
@@ -889,6 +889,7 @@ nsresult HTMLFormElement::SubmitSubmission(
|
|||||||
loadState->SetTextDirectiveUserActivation(
|
loadState->SetTextDirectiveUserActivation(
|
||||||
doc->ConsumeTextDirectiveUserActivation() ||
|
doc->ConsumeTextDirectiveUserActivation() ||
|
||||||
hasValidUserGestureActivation);
|
hasValidUserGestureActivation);
|
||||||
|
loadState->SetFormDataEntryList(aFormSubmission->GetFormData());
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> nodePrincipal = NodePrincipal();
|
nsCOMPtr<nsIPrincipal> nodePrincipal = NodePrincipal();
|
||||||
rv = container->OnLinkClickSync(this, loadState, false, nodePrincipal);
|
rv = container->OnLinkClickSync(this, loadState, false, nodePrincipal);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "mozilla/dom/AncestorIterator.h"
|
#include "mozilla/dom/AncestorIterator.h"
|
||||||
#include "mozilla/dom/Directory.h"
|
#include "mozilla/dom/Directory.h"
|
||||||
#include "mozilla/dom/File.h"
|
#include "mozilla/dom/File.h"
|
||||||
|
#include "mozilla/dom/FormData.h"
|
||||||
#include "mozilla/StaticPrefs_dom.h"
|
#include "mozilla/StaticPrefs_dom.h"
|
||||||
#include "mozilla/RandomNum.h"
|
#include "mozilla/RandomNum.h"
|
||||||
|
|
||||||
@@ -770,6 +771,7 @@ void GetEnumAttr(nsGenericHTMLElement* aContent, nsAtom* atom,
|
|||||||
nsresult HTMLFormSubmission::GetFromForm(HTMLFormElement* aForm,
|
nsresult HTMLFormSubmission::GetFromForm(HTMLFormElement* aForm,
|
||||||
nsGenericHTMLElement* aSubmitter,
|
nsGenericHTMLElement* aSubmitter,
|
||||||
NotNull<const Encoding*>& aEncoding,
|
NotNull<const Encoding*>& aEncoding,
|
||||||
|
FormData* aFormData,
|
||||||
HTMLFormSubmission** aFormSubmission) {
|
HTMLFormSubmission** aFormSubmission) {
|
||||||
// Get all the information necessary to encode the form data
|
// Get all the information necessary to encode the form data
|
||||||
NS_ASSERTION(aForm->GetComposedDoc(),
|
NS_ASSERTION(aForm->GetComposedDoc(),
|
||||||
@@ -864,6 +866,13 @@ nsresult HTMLFormSubmission::GetFromForm(HTMLFormElement* aForm,
|
|||||||
new FSURLEncoded(actionURL, target, aEncoding, method, doc, aSubmitter);
|
new FSURLEncoded(actionURL, target, aEncoding, method, doc, aSubmitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We store the FormData here to be able to set it on the load state when we
|
||||||
|
// submit the submission. It's used for the #navigate algorithm in the HTML
|
||||||
|
// spec and is only ever needed when the method is POST.
|
||||||
|
if (method == NS_FORM_METHOD_POST) {
|
||||||
|
(*aFormSubmission)->mFormData = aFormData;
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class HTMLFormSubmission {
|
|||||||
static nsresult GetFromForm(HTMLFormElement* aForm,
|
static nsresult GetFromForm(HTMLFormElement* aForm,
|
||||||
nsGenericHTMLElement* aSubmitter,
|
nsGenericHTMLElement* aSubmitter,
|
||||||
NotNull<const Encoding*>& aEncoding,
|
NotNull<const Encoding*>& aEncoding,
|
||||||
|
FormData* aFormData,
|
||||||
HTMLFormSubmission** aFormSubmission);
|
HTMLFormSubmission** aFormSubmission);
|
||||||
|
|
||||||
MOZ_COUNTED_DTOR_VIRTUAL(HTMLFormSubmission)
|
MOZ_COUNTED_DTOR_VIRTUAL(HTMLFormSubmission)
|
||||||
@@ -111,6 +112,8 @@ class HTMLFormSubmission {
|
|||||||
|
|
||||||
virtual DialogFormSubmission* GetAsDialogSubmission() { return nullptr; }
|
virtual DialogFormSubmission* GetAsDialogSubmission() { return nullptr; }
|
||||||
|
|
||||||
|
FormData* GetFormData() const { return mFormData; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Can only be constructed by subclasses.
|
* Can only be constructed by subclasses.
|
||||||
@@ -129,6 +132,8 @@ class HTMLFormSubmission {
|
|||||||
// The character encoding of this form submission
|
// The character encoding of this form submission
|
||||||
mozilla::NotNull<const mozilla::Encoding*> mEncoding;
|
mozilla::NotNull<const mozilla::Encoding*> mEncoding;
|
||||||
|
|
||||||
|
RefPtr<FormData> mFormData;
|
||||||
|
|
||||||
// Keep track of whether this form submission was user-initiated or not
|
// Keep track of whether this form submission was user-initiated or not
|
||||||
bool mInitiatedFromUserInput;
|
bool mInitiatedFromUserInput;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -524,7 +524,7 @@ bool Navigation::FireTraverseNavigateEvent(
|
|||||||
aCx, NavigationType::Traverse, destination,
|
aCx, NavigationType::Traverse, destination,
|
||||||
aUserInvolvement.valueOr(UserNavigationInvolvement::None),
|
aUserInvolvement.valueOr(UserNavigationInvolvement::None),
|
||||||
/* aSourceElement */ nullptr,
|
/* aSourceElement */ nullptr,
|
||||||
/* aFormDataEntryList*/ Nothing(),
|
/* aFormDataEntryList*/ nullptr,
|
||||||
/* aClassicHistoryAPIState */ nullptr,
|
/* aClassicHistoryAPIState */ nullptr,
|
||||||
/* aDownloadRequestFilename */ VoidString());
|
/* aDownloadRequestFilename */ VoidString());
|
||||||
}
|
}
|
||||||
@@ -533,7 +533,7 @@ bool Navigation::FireTraverseNavigateEvent(
|
|||||||
bool Navigation::FirePushReplaceReloadNavigateEvent(
|
bool Navigation::FirePushReplaceReloadNavigateEvent(
|
||||||
JSContext* aCx, NavigationType aNavigationType, nsIURI* aDestinationURL,
|
JSContext* aCx, NavigationType aNavigationType, nsIURI* aDestinationURL,
|
||||||
bool aIsSameDocument, Maybe<UserNavigationInvolvement> aUserInvolvement,
|
bool aIsSameDocument, Maybe<UserNavigationInvolvement> aUserInvolvement,
|
||||||
Element* aSourceElement, Maybe<const FormData&> aFormDataEntryList,
|
Element* aSourceElement, already_AddRefed<FormData> aFormDataEntryList,
|
||||||
nsIStructuredCloneContainer* aNavigationAPIState,
|
nsIStructuredCloneContainer* aNavigationAPIState,
|
||||||
nsIStructuredCloneContainer* aClassicHistoryAPIState) {
|
nsIStructuredCloneContainer* aClassicHistoryAPIState) {
|
||||||
// To not unnecessarily create an event that's never used, step 1 and step 2
|
// To not unnecessarily create an event that's never used, step 1 and step 2
|
||||||
@@ -551,7 +551,7 @@ bool Navigation::FirePushReplaceReloadNavigateEvent(
|
|||||||
return InnerFireNavigateEvent(
|
return InnerFireNavigateEvent(
|
||||||
aCx, aNavigationType, destination,
|
aCx, aNavigationType, destination,
|
||||||
aUserInvolvement.valueOr(UserNavigationInvolvement::None), aSourceElement,
|
aUserInvolvement.valueOr(UserNavigationInvolvement::None), aSourceElement,
|
||||||
aFormDataEntryList, aClassicHistoryAPIState,
|
std::move(aFormDataEntryList), aClassicHistoryAPIState,
|
||||||
/* aDownloadRequestFilename */ VoidString());
|
/* aDownloadRequestFilename */ VoidString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,7 +574,7 @@ bool Navigation::FireDownloadRequestNavigateEvent(
|
|||||||
// Step 8
|
// Step 8
|
||||||
return InnerFireNavigateEvent(
|
return InnerFireNavigateEvent(
|
||||||
aCx, NavigationType::Push, destination, aUserInvolvement, aSourceElement,
|
aCx, NavigationType::Push, destination, aUserInvolvement, aSourceElement,
|
||||||
/* aFormDataEntryList */ Nothing(),
|
/* aFormDataEntryList */ nullptr,
|
||||||
/* aClassicHistoryAPIState */ nullptr, aFilename);
|
/* aClassicHistoryAPIState */ nullptr, aFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,7 +663,7 @@ bool Navigation::InnerFireNavigateEvent(
|
|||||||
JSContext* aCx, NavigationType aNavigationType,
|
JSContext* aCx, NavigationType aNavigationType,
|
||||||
NavigationDestination* aDestination,
|
NavigationDestination* aDestination,
|
||||||
UserNavigationInvolvement aUserInvolvement, Element* aSourceElement,
|
UserNavigationInvolvement aUserInvolvement, Element* aSourceElement,
|
||||||
Maybe<const FormData&> aFormDataEntryList,
|
already_AddRefed<FormData> aFormDataEntryList,
|
||||||
nsIStructuredCloneContainer* aClassicHistoryAPIState,
|
nsIStructuredCloneContainer* aClassicHistoryAPIState,
|
||||||
const nsAString& aDownloadRequestFilename) {
|
const nsAString& aDownloadRequestFilename) {
|
||||||
// Step 1
|
// Step 1
|
||||||
@@ -758,7 +758,7 @@ bool Navigation::InnerFireNavigateEvent(
|
|||||||
init.mUserInitiated = aUserInvolvement != UserNavigationInvolvement::None;
|
init.mUserInitiated = aUserInvolvement != UserNavigationInvolvement::None;
|
||||||
|
|
||||||
// Step 24
|
// Step 24
|
||||||
init.mFormData = aFormDataEntryList ? aFormDataEntryList->Clone() : nullptr;
|
init.mFormData = aFormDataEntryList;
|
||||||
|
|
||||||
// Step 25
|
// Step 25
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!mOngoingNavigateEvent);
|
MOZ_DIAGNOSTIC_ASSERT(!mOngoingNavigateEvent);
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class Navigation final : public DOMEventTargetHelper {
|
|||||||
MOZ_CAN_RUN_SCRIPT bool FirePushReplaceReloadNavigateEvent(
|
MOZ_CAN_RUN_SCRIPT bool FirePushReplaceReloadNavigateEvent(
|
||||||
JSContext* aCx, NavigationType aNavigationType, nsIURI* aDestinationURL,
|
JSContext* aCx, NavigationType aNavigationType, nsIURI* aDestinationURL,
|
||||||
bool aIsSameDocument, Maybe<UserNavigationInvolvement> aUserInvolvement,
|
bool aIsSameDocument, Maybe<UserNavigationInvolvement> aUserInvolvement,
|
||||||
Element* aSourceElement, Maybe<const FormData&> aFormDataEntryList,
|
Element* aSourceElement, already_AddRefed<FormData> aFormDataEntryList,
|
||||||
nsIStructuredCloneContainer* aNavigationAPIState,
|
nsIStructuredCloneContainer* aNavigationAPIState,
|
||||||
nsIStructuredCloneContainer* aClassicHistoryAPIState);
|
nsIStructuredCloneContainer* aClassicHistoryAPIState);
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ class Navigation final : public DOMEventTargetHelper {
|
|||||||
JSContext* aCx, NavigationType aNavigationType,
|
JSContext* aCx, NavigationType aNavigationType,
|
||||||
NavigationDestination* aDestination,
|
NavigationDestination* aDestination,
|
||||||
UserNavigationInvolvement aUserInvolvement, Element* aSourceElement,
|
UserNavigationInvolvement aUserInvolvement, Element* aSourceElement,
|
||||||
Maybe<const FormData&> aFormDataEntryList,
|
already_AddRefed<FormData> aFormDataEntryList,
|
||||||
nsIStructuredCloneContainer* aClassicHistoryAPIState,
|
nsIStructuredCloneContainer* aClassicHistoryAPIState,
|
||||||
const nsAString& aDownloadRequestFilename);
|
const nsAString& aDownloadRequestFilename);
|
||||||
|
|
||||||
|
|||||||
@@ -2840,6 +2840,24 @@ bool NS_IsAboutSrcdoc(nsIURI* uri) {
|
|||||||
return spec.EqualsLiteral("about:srcdoc");
|
return spec.EqualsLiteral("about:srcdoc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://fetch.spec.whatwg.org/#fetch-scheme
|
||||||
|
bool NS_IsFetchScheme(nsIURI* uri) {
|
||||||
|
for (const auto& scheme : {
|
||||||
|
"http",
|
||||||
|
"https",
|
||||||
|
"about",
|
||||||
|
"blob",
|
||||||
|
"data",
|
||||||
|
"file",
|
||||||
|
}) {
|
||||||
|
if (uri->SchemeIs(scheme)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult NS_GenerateHostPort(const nsCString& host, int32_t port,
|
nsresult NS_GenerateHostPort(const nsCString& host, int32_t port,
|
||||||
nsACString& hostLine) {
|
nsACString& hostLine) {
|
||||||
if (strchr(host.get(), ':')) {
|
if (strchr(host.get(), ':')) {
|
||||||
|
|||||||
@@ -946,6 +946,12 @@ bool NS_IsAboutBlankAllowQueryAndFragment(nsIURI* uri);
|
|||||||
*/
|
*/
|
||||||
bool NS_IsAboutSrcdoc(nsIURI* uri);
|
bool NS_IsAboutSrcdoc(nsIURI* uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether a URI has an "about", "blob", "data", "file", or an HTTP(S)
|
||||||
|
* scheme.
|
||||||
|
*/
|
||||||
|
bool NS_IsFetchScheme(nsIURI* uri);
|
||||||
|
|
||||||
nsresult NS_GenerateHostPort(const nsCString& host, int32_t port,
|
nsresult NS_GenerateHostPort(const nsCString& host, int32_t port,
|
||||||
nsACString& hostLine);
|
nsACString& hostLine);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user