зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1588715 - Implement SubmitEvent; r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D62030 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
338c49f1f0
Коммит
5683fcf7c8
|
@ -344,6 +344,10 @@ const kEventConstructors = {
|
||||||
},
|
},
|
||||||
chromeOnly: true,
|
chromeOnly: true,
|
||||||
},
|
},
|
||||||
|
SubmitEvent: { create (aName, aProps) {
|
||||||
|
return new SubmitEvent(aName, aProps);
|
||||||
|
},
|
||||||
|
},
|
||||||
TCPSocketErrorEvent: { create(aName, aProps) {
|
TCPSocketErrorEvent: { create(aName, aProps) {
|
||||||
return new TCPSocketErrorEvent(aName, aProps);
|
return new TCPSocketErrorEvent(aName, aProps);
|
||||||
},
|
},
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "HTMLFormSubmissionConstants.h"
|
#include "HTMLFormSubmissionConstants.h"
|
||||||
#include "mozilla/dom/FormData.h"
|
#include "mozilla/dom/FormData.h"
|
||||||
#include "mozilla/dom/FormDataEvent.h"
|
#include "mozilla/dom/FormDataEvent.h"
|
||||||
|
#include "mozilla/dom/SubmitEvent.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
#include "nsIFormSubmitObserver.h"
|
#include "nsIFormSubmitObserver.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
|
@ -260,10 +261,16 @@ void HTMLFormElement::MaybeSubmit(Element* aSubmitter) {
|
||||||
// dispatch the event. It makes sure that event is not handled if the window
|
// dispatch the event. It makes sure that event is not handled if the window
|
||||||
// is being destroyed.
|
// is being destroyed.
|
||||||
if (RefPtr<PresShell> presShell = doc->GetPresShell()) {
|
if (RefPtr<PresShell> presShell = doc->GetPresShell()) {
|
||||||
InternalFormEvent event(true, eFormSubmit);
|
SubmitEventInit init;
|
||||||
event.mOriginator = aSubmitter;
|
init.mBubbles = true;
|
||||||
|
init.mCancelable = true;
|
||||||
|
init.mSubmitter =
|
||||||
|
aSubmitter ? nsGenericHTMLElement::FromNode(aSubmitter) : nullptr;
|
||||||
|
RefPtr<SubmitEvent> event =
|
||||||
|
SubmitEvent::Constructor(this, NS_LITERAL_STRING("submit"), init);
|
||||||
|
event->SetTrusted(true);
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
presShell->HandleDOMEventWithTarget(this, &event, &status);
|
presShell->HandleDOMEventWithTarget(this, event, &status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +297,7 @@ void HTMLFormElement::Submit(ErrorResult& aRv) {
|
||||||
mPendingSubmission = nullptr;
|
mPendingSubmission = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
aRv = DoSubmitOrReset(nullptr, eFormSubmit);
|
aRv = DoSubmit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
|
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
|
||||||
|
@ -541,9 +548,12 @@ nsresult HTMLFormElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||||
|
|
||||||
if (aVisitor.mEventStatus == nsEventStatus_eIgnore) {
|
if (aVisitor.mEventStatus == nsEventStatus_eIgnore) {
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case eFormReset:
|
case eFormReset: {
|
||||||
|
DoReset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case eFormSubmit: {
|
case eFormSubmit: {
|
||||||
if (mPendingSubmission && msg == eFormSubmit) {
|
if (mPendingSubmission) {
|
||||||
// tell the form to forget a possible pending submission.
|
// tell the form to forget a possible pending submission.
|
||||||
// the reason is that the script returned true (the event was
|
// the reason is that the script returned true (the event was
|
||||||
// ignored) so if there is a stored submission, it will miss
|
// ignored) so if there is a stored submission, it will miss
|
||||||
|
@ -551,7 +561,7 @@ nsresult HTMLFormElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||||
// to forget it and the form element will build a new one
|
// to forget it and the form element will build a new one
|
||||||
mPendingSubmission = nullptr;
|
mPendingSubmission = nullptr;
|
||||||
}
|
}
|
||||||
DoSubmitOrReset(aVisitor.mEvent, msg);
|
DoSubmit(aVisitor.mDOMEvent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -576,36 +586,13 @@ nsresult HTMLFormElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult HTMLFormElement::DoSubmitOrReset(WidgetEvent* aEvent,
|
nsresult HTMLFormElement::DoReset() {
|
||||||
EventMessage aMessage) {
|
|
||||||
// Make sure the presentation is up-to-date
|
// Make sure the presentation is up-to-date
|
||||||
Document* doc = GetComposedDoc();
|
Document* doc = GetComposedDoc();
|
||||||
if (doc) {
|
if (doc) {
|
||||||
doc->FlushPendingNotifications(FlushType::ContentAndNotify);
|
doc->FlushPendingNotifications(FlushType::ContentAndNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JBK Don't get form frames anymore - bug 34297
|
|
||||||
|
|
||||||
// Submit or Reset the form
|
|
||||||
if (eFormReset == aMessage) {
|
|
||||||
return DoReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eFormSubmit == aMessage) {
|
|
||||||
// Don't submit if we're not in a document or if we're in
|
|
||||||
// a sandboxed frame and form submit is disabled.
|
|
||||||
if (mIsConstructingEntryList || !doc ||
|
|
||||||
(doc->GetSandboxFlags() & SANDBOXED_FORMS)) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
return DoSubmit(aEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(false);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult HTMLFormElement::DoReset() {
|
|
||||||
mEverTriedInvalidSubmit = false;
|
mEverTriedInvalidSubmit = false;
|
||||||
// JBK walk the elements[] array instead of form frame controls - bug 34297
|
// JBK walk the elements[] array instead of form frame controls - bug 34297
|
||||||
uint32_t numElements = GetElementCount();
|
uint32_t numElements = GetElementCount();
|
||||||
|
@ -626,8 +613,21 @@ nsresult HTMLFormElement::DoReset() {
|
||||||
return rv; \
|
return rv; \
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult HTMLFormElement::DoSubmit(WidgetEvent* aEvent) {
|
nsresult HTMLFormElement::DoSubmit(Event* aEvent) {
|
||||||
NS_ASSERTION(GetComposedDoc(), "Should never get here without a current doc");
|
Document* doc = GetComposedDoc();
|
||||||
|
NS_ASSERTION(doc, "Should never get here without a current doc");
|
||||||
|
|
||||||
|
// Make sure the presentation is up-to-date
|
||||||
|
if (doc) {
|
||||||
|
doc->FlushPendingNotifications(FlushType::ContentAndNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't submit if we're not in a document or if we're in
|
||||||
|
// a sandboxed frame and form submit is disabled.
|
||||||
|
if (mIsConstructingEntryList || !doc ||
|
||||||
|
(doc->GetSandboxFlags() & SANDBOXED_FORMS)) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (mIsSubmitting) {
|
if (mIsSubmitting) {
|
||||||
NS_WARNING("Preventing double form submission");
|
NS_WARNING("Preventing double form submission");
|
||||||
|
@ -685,21 +685,15 @@ nsresult HTMLFormElement::DoSubmit(WidgetEvent* aEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult HTMLFormElement::BuildSubmission(HTMLFormSubmission** aFormSubmission,
|
nsresult HTMLFormElement::BuildSubmission(HTMLFormSubmission** aFormSubmission,
|
||||||
WidgetEvent* aEvent) {
|
Event* aEvent) {
|
||||||
NS_ASSERTION(!mPendingSubmission, "tried to build two submissions!");
|
NS_ASSERTION(!mPendingSubmission, "tried to build two submissions!");
|
||||||
|
|
||||||
// Get the originating frame (failure is non-fatal)
|
// Get the originating frame
|
||||||
nsGenericHTMLElement* originatingElement = nullptr;
|
nsGenericHTMLElement* originatingElement = nullptr;
|
||||||
if (aEvent) {
|
if (aEvent) {
|
||||||
InternalFormEvent* formEvent = aEvent->AsFormEvent();
|
SubmitEvent* submitEvent = aEvent->AsSubmitEvent();
|
||||||
if (formEvent) {
|
if (submitEvent) {
|
||||||
nsIContent* originator = formEvent->mOriginator;
|
originatingElement = submitEvent->GetSubmitter();
|
||||||
if (originator) {
|
|
||||||
if (!originator->IsHTMLElement()) {
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
originatingElement = static_cast<nsGenericHTMLElement*>(originator);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -430,7 +430,6 @@ class HTMLFormElement final : public nsGenericHTMLElement,
|
||||||
RefPtr<HTMLFormElement> mForm;
|
RefPtr<HTMLFormElement> mForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult DoSubmitOrReset(WidgetEvent* aEvent, EventMessage aMessage);
|
|
||||||
nsresult DoReset();
|
nsresult DoReset();
|
||||||
|
|
||||||
// Async callback to handle removal of our default submit
|
// Async callback to handle removal of our default submit
|
||||||
|
@ -442,12 +441,11 @@ class HTMLFormElement final : public nsGenericHTMLElement,
|
||||||
//
|
//
|
||||||
/**
|
/**
|
||||||
* Attempt to submit (submission might be deferred)
|
* Attempt to submit (submission might be deferred)
|
||||||
* (called by DoSubmitOrReset)
|
|
||||||
*
|
*
|
||||||
* @param aPresContext the presentation context
|
* @param aPresContext the presentation context
|
||||||
* @param aEvent the DOM event that was passed to us for the submit
|
* @param aEvent the DOM event that was passed to us for the submit
|
||||||
*/
|
*/
|
||||||
nsresult DoSubmit(WidgetEvent* aEvent);
|
nsresult DoSubmit(Event* aEvent = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the submission object (called by DoSubmit)
|
* Prepare the submission object (called by DoSubmit)
|
||||||
|
@ -455,8 +453,7 @@ class HTMLFormElement final : public nsGenericHTMLElement,
|
||||||
* @param aFormSubmission the submission object
|
* @param aFormSubmission the submission object
|
||||||
* @param aEvent the DOM event that was passed to us for the submit
|
* @param aEvent the DOM event that was passed to us for the submit
|
||||||
*/
|
*/
|
||||||
nsresult BuildSubmission(HTMLFormSubmission** aFormSubmission,
|
nsresult BuildSubmission(HTMLFormSubmission** aFormSubmission, Event* aEvent);
|
||||||
WidgetEvent* aEvent);
|
|
||||||
/**
|
/**
|
||||||
* Perform the submission (called by DoSubmit and FlushPendingSubmission)
|
* Perform the submission (called by DoSubmit and FlushPendingSubmission)
|
||||||
*
|
*
|
||||||
|
|
|
@ -1052,6 +1052,8 @@ var interfaceNamesInGlobalScope = [
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
{ name: "SubtleCrypto", insecureContext: true },
|
{ name: "SubtleCrypto", insecureContext: true },
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
|
{ name: "SubmitEvent", insecureContext: true },
|
||||||
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
{ name: "SVGAElement", insecureContext: true },
|
{ name: "SVGAElement", insecureContext: true },
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
{ name: "SVGAngle", insecureContext: true },
|
{ name: "SVGAngle", insecureContext: true },
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submitevent
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Exposed=Window]
|
||||||
|
interface SubmitEvent : Event {
|
||||||
|
constructor(DOMString type, optional SubmitEventInit eventInitDict = {});
|
||||||
|
|
||||||
|
readonly attribute HTMLElement? submitter;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary SubmitEventInit : EventInit {
|
||||||
|
HTMLElement? submitter = null;
|
||||||
|
};
|
|
@ -1085,6 +1085,7 @@ GENERATED_EVENTS_WEBIDL_FILES = [
|
||||||
'ScrollViewChangeEvent.webidl',
|
'ScrollViewChangeEvent.webidl',
|
||||||
'SecurityPolicyViolationEvent.webidl',
|
'SecurityPolicyViolationEvent.webidl',
|
||||||
'StyleSheetApplicableStateChangeEvent.webidl',
|
'StyleSheetApplicableStateChangeEvent.webidl',
|
||||||
|
'SubmitEvent.webidl',
|
||||||
'TCPServerSocketEvent.webidl',
|
'TCPServerSocketEvent.webidl',
|
||||||
'TCPSocketErrorEvent.webidl',
|
'TCPSocketErrorEvent.webidl',
|
||||||
'TCPSocketEvent.webidl',
|
'TCPSocketEvent.webidl',
|
||||||
|
|
|
@ -723,28 +723,6 @@ prefs: [dom.security.featurePolicy.enabled:true, dom.security.featurePolicy.expe
|
||||||
[FormDataEvent interface object length]
|
[FormDataEvent interface object length]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[SubmitEvent interface: attribute submitter]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[SubmitEvent interface: existence and properties of interface prototype object's @@unscopables property]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[SubmitEvent interface object length]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[SubmitEvent interface: existence and properties of interface prototype object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[SubmitEvent interface: existence and properties of interface object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[SubmitEvent interface: existence and properties of interface prototype object's "constructor" property]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[SubmitEvent interface object name]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
|
|
||||||
[idlharness.https.html?include=(Document|Window)]
|
[idlharness.https.html?include=(Document|Window)]
|
||||||
[Document interface: documentWithHandlers must inherit property "onsecuritypolicyviolation" with the proper type]
|
[Document interface: documentWithHandlers must inherit property "onsecuritypolicyviolation" with the proper type]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
[SubmitEvent.window.html]
|
|
||||||
[Successful SubmitEvent constructor]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Failing SubmitEvent constructor]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Successful SubmitEvent constructor; empty dictionary]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Successful SubmitEvent constructor; missing dictionary]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Successful SubmitEvent constructor; null/undefined submitter]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Successful SubmitEvent constructor; null/undefined dictionary]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
[form-submission-algorithm.html]
|
|
||||||
[firing an event named submit; form.requestSubmit(submitter)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[firing an event named submit; clicking a submit button]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[firing an event named submit; form.requestSubmit(null)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[firing an event named submit; form.requestSubmit()]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
[implicit-submission.optional.html]
|
[implicit-submission.optional.html]
|
||||||
[Submit event with a submit button]
|
[Submit event with a submit button]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Submit event with no submit button]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче