Changeset 277257 in webkit


Ignore:
Timestamp:
May 10, 2021 12:16:13 AM (15 months ago)
Author:
commit-queue@webkit.org
Message:

Implement <form>.requestSubmit()
https://bugs.webkit.org/show_bug.cgi?id=197958

Patch by Rob Buis <rbuis@igalia.com> on 2021-05-10
Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Update improved test results and import requestSubmit tests.

  • web-platform-tests/html/dom/idlharness.https-expected.txt:
  • web-platform-tests/html/semantics/forms/form-submission-0/request-submit-activation-expected.txt: Added.
  • web-platform-tests/html/semantics/forms/form-submission-0/request-submit-activation.html: Added.
  • web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit-autofocus-expected.txt: Added.
  • web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit-autofocus.html: Added.
  • web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit-expected.txt:
  • web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit.html:

Source/WebCore:

Implement the requestSubmit method as defined here [1].

Behavior matches Chrome and Firefox.

[1] https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit

Tests: imported/w3c/web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit.html

imported/w3c/web-platform-tests/html/semantics/forms/form-submission-0/request-submit-activation.html
imported/w3c/web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit-autofocus.html

  • html/HTMLButtonElement.cpp:

(WebCore::HTMLButtonElement::defaultEventHandler):
(WebCore::HTMLButtonElement::isSubmitButton const):

  • html/HTMLButtonElement.h:
  • html/HTMLFormControlElement.h:

(WebCore::HTMLFormControlElement::isSubmitButton const):

  • html/HTMLFormElement.cpp:

(WebCore::HTMLFormElement::submitImplicitly):
(WebCore::HTMLFormElement::submitIfPossible):
(WebCore::HTMLFormElement::requestSubmit):
(WebCore::HTMLFormElement::findSubmitButton):
(WebCore::HTMLFormElement::submit):
(WebCore::HTMLFormElement::effectiveTarget const):
(WebCore::HTMLFormElement::findSubmitter const):
(WebCore::HTMLFormElement::reportValidity):
(WebCore::HTMLFormElement::prepareForSubmission): Deleted.
(WebCore::HTMLFormElement::findSubmitButton const): Deleted.

  • html/HTMLFormElement.h:
  • html/HTMLFormElement.idl:
  • html/HTMLInputElement.h:
  • html/ImageInputType.cpp:

(WebCore::ImageInputType::handleDOMActivateEvent):

  • html/ImageInputType.h:
  • html/InputType.h:

(WebCore::InputType::isSubmitButton const):

  • html/SubmitInputType.cpp:

(WebCore::SubmitInputType::handleDOMActivateEvent):

  • loader/FormSubmission.cpp:

(WebCore::FormSubmission::create):

  • loader/FormSubmission.h:

Source/WTF:

Add requestSubmit as experimental feature, disabled by default.

  • Scripts/Preferences/WebPreferencesExperimental.yaml:

LayoutTests:

Update improved test results.

  • platform/gtk/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
  • platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
  • platform/mac-wk1/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
  • platform/mac-wk2/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
  • platform/wpe/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
Location:
trunk
Files:
4 added
26 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r277230 r277257  
     12021-05-10  Rob Buis  <rbuis@igalia.com>
     2
     3        Implement <form>.requestSubmit()
     4        https://bugs.webkit.org/show_bug.cgi?id=197958
     5
     6        Reviewed by Darin Adler.
     7
     8        Update improved test results.
     9
     10        * platform/gtk/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
     11        * platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
     12        * platform/mac-wk1/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
     13        * platform/mac-wk2/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
     14        * platform/wpe/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
     15
    1162021-05-08  Ricky Mondello  <rmondello@apple.com>
    217
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r277160 r277257  
     12021-05-10  Rob Buis  <rbuis@igalia.com>
     2
     3        Implement <form>.requestSubmit()
     4        https://bugs.webkit.org/show_bug.cgi?id=197958
     5
     6        Reviewed by Darin Adler.
     7
     8        Update improved test results and import requestSubmit tests.
     9
     10        * web-platform-tests/html/dom/idlharness.https-expected.txt:
     11        * web-platform-tests/html/semantics/forms/form-submission-0/request-submit-activation-expected.txt: Added.
     12        * web-platform-tests/html/semantics/forms/form-submission-0/request-submit-activation.html: Added.
     13        * web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit-autofocus-expected.txt: Added.
     14        * web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit-autofocus.html: Added.
     15        * web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit-expected.txt:
     16        * web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit.html:
     17
    1182021-05-06  Tim Nguyen  <ntim@apple.com>
    219
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt

    r276777 r277257  
    16991699PASS HTMLFormElement interface: attribute length
    17001700PASS HTMLFormElement interface: operation submit()
    1701 FAIL HTMLFormElement interface: operation requestSubmit(HTMLElement) assert_own_property: interface prototype object missing non-static operation expected property "requestSubmit" missing
     1701PASS HTMLFormElement interface: operation requestSubmit(HTMLElement)
    17021702PASS HTMLFormElement interface: operation reset()
    17031703PASS HTMLFormElement interface: operation checkValidity()
     
    17191719PASS HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type
    17201720PASS HTMLFormElement interface: document.createElement("form") must inherit property "submit()" with the proper type
    1721 FAIL HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(HTMLElement)" with the proper type assert_inherits: property "requestSubmit" not found in prototype chain
    1722 FAIL HTMLFormElement interface: calling requestSubmit(HTMLElement) on document.createElement("form") with too few arguments must throw TypeError assert_inherits: property "requestSubmit" not found in prototype chain
     1721PASS HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(HTMLElement)" with the proper type
     1722PASS HTMLFormElement interface: calling requestSubmit(HTMLElement) on document.createElement("form") with too few arguments must throw TypeError
    17231723PASS HTMLFormElement interface: document.createElement("form") must inherit property "reset()" with the proper type
    17241724PASS HTMLFormElement interface: document.createElement("form") must inherit property "checkValidity()" with the proper type
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit-expected.txt

    r267646 r277257  
     1
     2
    13
    24
     
    1012
    1113PASS Passing an element which is not a submit button should throw
    12 FAIL Passing a submit button not owned by the context object should throw assert_throws_dom: function "() => {
    13     form.requestSubmit(submitButton);
    14   }" threw object "TypeError: form.requestSubmit is not a function. (In 'form.requestSubmit(submitButton)', 'form.requestSubmit' is undefined)" that is not a DOMException NotFoundError: property "code" is equal to undefined, expected 8
    15 FAIL requestSubmit() should accept button[type=submit], input[type=submit], and input[type=image] form.requestSubmit is not a function. (In 'form.requestSubmit(control)', 'form.requestSubmit' is undefined)
    16 FAIL requestSubmit() should trigger interactive form validation form.requestSubmit is not a function. (In 'form.requestSubmit()', 'form.requestSubmit' is undefined)
    17 FAIL requestSubmit() doesn't run form submission reentrantly form.requestSubmit is not a function. (In 'form.requestSubmit()', 'form.requestSubmit' is undefined)
    18 FAIL requestSubmit() doesn't run interactive validation reentrantly form.requestSubmit is not a function. (In 'form.requestSubmit()', 'form.requestSubmit' is undefined)
    19 FAIL requestSubmit() for a disconnected form should not submit the form form.requestSubmit is not a function. (In 'form.requestSubmit()', 'form.requestSubmit' is undefined)
    20 FAIL The value of the submitter should be appended, and form* attributes of the submitter should be handled. form.requestSubmit is not a function. (In 'form.requestSubmit(form.querySelector('[type=submit]'))', 'form.requestSubmit' is undefined)
     14PASS Passing a submit button not owned by the context object should throw
     15PASS requestSubmit() should accept button[type=submit], input[type=submit], and input[type=image]
     16PASS requestSubmit() should trigger interactive form validation
     17PASS requestSubmit() doesn't run form submission reentrantly
     18PASS requestSubmit() doesn't run interactive validation reentrantly
     19PASS requestSubmit() for a disconnected form should not submit the form
     20PASS The value of the submitter should be appended, and form* attributes of the submitter should be handled.
     21PASS The constructed FormData object should not contain an entry for the submit button that was used to submit the form.
     22PASS Using requestSubmit on a disabled button (via disabled attribute) should trigger submit but not be visible in FormData
    2123
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit.html

    r263987 r277257  
    174174}, 'The value of the submitter should be appended, and form* ' +
    175175    'attributes of the submitter should be handled.');
     176
     177test(() => {
     178  document.body.insertAdjacentHTML('afterbegin', `<form>
     179      <input name="n1" value="v1">
     180      <button type="submit" name="n2" value="v2"></button>
     181      </form>
     182      <form id="form2"></form>`);
     183  let form = document.querySelector('form');
     184  let formDataInEvent = null;
     185  let submitter = form.querySelector('button[type=submit]');
     186  form.addEventListener('submit', e => {
     187    e.preventDefault();
     188    formDataInEvent = new FormData(e.target);
     189  });
     190
     191  form.requestSubmit(submitter);
     192  assert_equals(formDataInEvent.get('n1'), 'v1');
     193  assert_false(formDataInEvent.has('n2'));
     194}, 'The constructed FormData object should not contain an entry for the submit button that was used to submit the form.');
     195
     196async_test(t => {
     197  document.body.insertAdjacentHTML('afterbegin', `<form>
     198      <button type="submit" name="n1" value="v1" disabled=""></button>
     199      </form>`);
     200  let form = document.querySelector('form');
     201  let formDataInEvent = null;
     202  let submitter = form.querySelector('button[type=submit]');
     203
     204  form.addEventListener("submit", t.step_func_done(ev => {
     205    ev.preventDefault();
     206    formDataInEvent = new FormData(ev.target);
     207    assert_false(formDataInEvent.has('n1'));
     208    assert_equals(ev.target, form);
     209  }));
     210
     211  form.requestSubmit(submitter);
     212
     213}, "Using requestSubmit on a disabled button (via disabled attribute) should trigger submit but not be visible in FormData");
     214
    176215</script>
  • trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt

    r276777 r277257  
    18481848PASS HTMLFormElement interface: attribute length
    18491849PASS HTMLFormElement interface: operation submit()
    1850 FAIL HTMLFormElement interface: operation requestSubmit(optional HTMLElement?) assert_own_property: interface prototype object missing non-static operation expected property "requestSubmit" missing
     1850PASS HTMLFormElement interface: operation requestSubmit(optional HTMLElement?)
    18511851PASS HTMLFormElement interface: operation reset()
    18521852PASS HTMLFormElement interface: operation checkValidity()
     
    18681868PASS HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type
    18691869PASS HTMLFormElement interface: document.createElement("form") must inherit property "submit()" with the proper type
    1870 FAIL HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type assert_inherits: property "requestSubmit" not found in prototype chain
    1871 FAIL HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError assert_inherits: property "requestSubmit" not found in prototype chain
     1870PASS HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type
     1871PASS HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError
    18721872PASS HTMLFormElement interface: document.createElement("form") must inherit property "reset()" with the proper type
    18731873PASS HTMLFormElement interface: document.createElement("form") must inherit property "checkValidity()" with the proper type
  • trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt

    r276777 r277257  
    18381838PASS HTMLFormElement interface: attribute length
    18391839PASS HTMLFormElement interface: operation submit()
    1840 FAIL HTMLFormElement interface: operation requestSubmit(optional HTMLElement?) assert_own_property: interface prototype object missing non-static operation expected property "requestSubmit" missing
     1840PASS HTMLFormElement interface: operation requestSubmit(optional HTMLElement?)
    18411841PASS HTMLFormElement interface: operation reset()
    18421842PASS HTMLFormElement interface: operation checkValidity()
     
    18581858PASS HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type
    18591859PASS HTMLFormElement interface: document.createElement("form") must inherit property "submit()" with the proper type
    1860 FAIL HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type assert_inherits: property "requestSubmit" not found in prototype chain
    1861 FAIL HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError assert_inherits: property "requestSubmit" not found in prototype chain
     1860PASS HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type
     1861PASS HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError
    18621862PASS HTMLFormElement interface: document.createElement("form") must inherit property "reset()" with the proper type
    18631863PASS HTMLFormElement interface: document.createElement("form") must inherit property "checkValidity()" with the proper type
  • trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt

    r276777 r277257  
    18481848PASS HTMLFormElement interface: attribute length
    18491849PASS HTMLFormElement interface: operation submit()
    1850 FAIL HTMLFormElement interface: operation requestSubmit(optional HTMLElement?) assert_own_property: interface prototype object missing non-static operation expected property "requestSubmit" missing
     1850PASS HTMLFormElement interface: operation requestSubmit(optional HTMLElement?)
    18511851PASS HTMLFormElement interface: operation reset()
    18521852PASS HTMLFormElement interface: operation checkValidity()
     
    18681868PASS HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type
    18691869PASS HTMLFormElement interface: document.createElement("form") must inherit property "submit()" with the proper type
    1870 FAIL HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type assert_inherits: property "requestSubmit" not found in prototype chain
    1871 FAIL HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError assert_inherits: property "requestSubmit" not found in prototype chain
     1870PASS HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type
     1871PASS HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError
    18721872PASS HTMLFormElement interface: document.createElement("form") must inherit property "reset()" with the proper type
    18731873PASS HTMLFormElement interface: document.createElement("form") must inherit property "checkValidity()" with the proper type
  • trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt

    r276777 r277257  
    18481848PASS HTMLFormElement interface: attribute length
    18491849PASS HTMLFormElement interface: operation submit()
    1850 FAIL HTMLFormElement interface: operation requestSubmit(optional HTMLElement?) assert_own_property: interface prototype object missing non-static operation expected property "requestSubmit" missing
     1850PASS HTMLFormElement interface: operation requestSubmit(optional HTMLElement?)
    18511851PASS HTMLFormElement interface: operation reset()
    18521852PASS HTMLFormElement interface: operation checkValidity()
     
    18681868PASS HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type
    18691869PASS HTMLFormElement interface: document.createElement("form") must inherit property "submit()" with the proper type
    1870 FAIL HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type assert_inherits: property "requestSubmit" not found in prototype chain
    1871 FAIL HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError assert_inherits: property "requestSubmit" not found in prototype chain
     1870PASS HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type
     1871PASS HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError
    18721872PASS HTMLFormElement interface: document.createElement("form") must inherit property "reset()" with the proper type
    18731873PASS HTMLFormElement interface: document.createElement("form") must inherit property "checkValidity()" with the proper type
  • trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt

    r276777 r277257  
    18481848PASS HTMLFormElement interface: attribute length
    18491849PASS HTMLFormElement interface: operation submit()
    1850 FAIL HTMLFormElement interface: operation requestSubmit(optional HTMLElement?) assert_own_property: interface prototype object missing non-static operation expected property "requestSubmit" missing
     1850PASS HTMLFormElement interface: operation requestSubmit(optional HTMLElement?)
    18511851PASS HTMLFormElement interface: operation reset()
    18521852PASS HTMLFormElement interface: operation checkValidity()
     
    18681868PASS HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type
    18691869PASS HTMLFormElement interface: document.createElement("form") must inherit property "submit()" with the proper type
    1870 FAIL HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type assert_inherits: property "requestSubmit" not found in prototype chain
    1871 FAIL HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError assert_inherits: property "requestSubmit" not found in prototype chain
     1870PASS HTMLFormElement interface: document.createElement("form") must inherit property "requestSubmit(optional HTMLElement?)" with the proper type
     1871PASS HTMLFormElement interface: calling requestSubmit(optional HTMLElement?) on document.createElement("form") with too few arguments must throw TypeError
    18721872PASS HTMLFormElement interface: document.createElement("form") must inherit property "reset()" with the proper type
    18731873PASS HTMLFormElement interface: document.createElement("form") must inherit property "checkValidity()" with the proper type
  • trunk/Source/WTF/ChangeLog

    r277245 r277257  
     12021-05-10  Rob Buis  <rbuis@igalia.com>
     2
     3        Implement <form>.requestSubmit()
     4        https://bugs.webkit.org/show_bug.cgi?id=197958
     5
     6        Reviewed by Darin Adler.
     7
     8        Add requestSubmit as experimental feature, disabled by default.
     9
     10        * Scripts/Preferences/WebPreferencesExperimental.yaml:
     11
    1122021-05-09  Darin Adler  <darin@apple.com>
    213
  • trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml

    r277024 r277257  
    865865      default: false
    866866
     867RequestSubmitEnabled:
     868  type: bool
     869  humanReadableName: "Form requestSubmit"
     870  humanReadableDescription: "Form requestSubmit method"
     871  defaultValue:
     872    WebKitLegacy:
     873      default: false
     874    WebKit:
     875      default: false
     876    WebCore:
     877      default: false
     878
    867879# FIXME: This is on by default in WebKit2. Perhaps we should consider turning it on for WebKitLegacy as well.
    868880ResizeObserverEnabled:
  • trunk/Source/WebCore/ChangeLog

    r277255 r277257  
     12021-05-10  Rob Buis  <rbuis@igalia.com>
     2
     3        Implement <form>.requestSubmit()
     4        https://bugs.webkit.org/show_bug.cgi?id=197958
     5
     6        Reviewed by Darin Adler.
     7
     8        Implement the requestSubmit method as defined here [1].
     9
     10        Behavior matches Chrome and Firefox.
     11
     12        [1] https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
     13
     14        Tests: imported/w3c/web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit.html
     15               imported/w3c/web-platform-tests/html/semantics/forms/form-submission-0/request-submit-activation.html
     16               imported/w3c/web-platform-tests/html/semantics/forms/the-form-element/form-requestsubmit-autofocus.html
     17
     18        * html/HTMLButtonElement.cpp:
     19        (WebCore::HTMLButtonElement::defaultEventHandler):
     20        (WebCore::HTMLButtonElement::isSubmitButton const):
     21        * html/HTMLButtonElement.h:
     22        * html/HTMLFormControlElement.h:
     23        (WebCore::HTMLFormControlElement::isSubmitButton const):
     24        * html/HTMLFormElement.cpp:
     25        (WebCore::HTMLFormElement::submitImplicitly):
     26        (WebCore::HTMLFormElement::submitIfPossible):
     27        (WebCore::HTMLFormElement::requestSubmit):
     28        (WebCore::HTMLFormElement::findSubmitButton):
     29        (WebCore::HTMLFormElement::submit):
     30        (WebCore::HTMLFormElement::effectiveTarget const):
     31        (WebCore::HTMLFormElement::findSubmitter const):
     32        (WebCore::HTMLFormElement::reportValidity):
     33        (WebCore::HTMLFormElement::prepareForSubmission): Deleted.
     34        (WebCore::HTMLFormElement::findSubmitButton const): Deleted.
     35        * html/HTMLFormElement.h:
     36        * html/HTMLFormElement.idl:
     37        * html/HTMLInputElement.h:
     38        * html/ImageInputType.cpp:
     39        (WebCore::ImageInputType::handleDOMActivateEvent):
     40        * html/ImageInputType.h:
     41        * html/InputType.h:
     42        (WebCore::InputType::isSubmitButton const):
     43        * html/SubmitInputType.cpp:
     44        (WebCore::SubmitInputType::handleDOMActivateEvent):
     45        * loader/FormSubmission.cpp:
     46        (WebCore::FormSubmission::create):
     47        * loader/FormSubmission.h:
     48
    1492021-05-09  Sam Weinig  <weinig@apple.com>
    250
  • trunk/Source/WebCore/html/HTMLButtonElement.cpp

    r272247 r277257  
    139139                if (m_type == SUBMIT) {
    140140                    SetForScope<bool> activatedSubmitState(m_isActivatedSubmit, true);
    141                     currentForm->prepareForSubmission(event);
     141                    currentForm->submitIfPossible(&event);
    142142                }
    143143
     
    238238}
    239239
     240bool HTMLButtonElement::isSubmitButton() const
     241{
     242    return m_type == SUBMIT;
     243}
     244
    240245} // namespace
  • trunk/Source/WebCore/html/HTMLButtonElement.h

    r259687 r277257  
    7777    bool computeWillValidate() const final;
    7878
     79    bool isSubmitButton() const final;
     80
    7981    Type m_type;
    8082    bool m_isActivatedSubmit;
  • trunk/Source/WebCore/html/HTMLFormControlElement.h

    r274029 r277257  
    127127    WEBCORE_EXPORT AutofillData autofillData() const;
    128128
     129    virtual bool isSubmitButton() const { return false; }
     130
    129131    using Node::ref;
    130132    using Node::deref;
  • trunk/Source/WebCore/html/HTMLFormElement.cpp

    r275103 r277257  
    4646#include "HTMLParserIdioms.h"
    4747#include "HTMLTableElement.h"
     48#include "InputTypeNames.h"
    4849#include "MIMETypeRegistry.h"
    4950#include "MixedContentChecker.h"
     
    211212    // Older iOS apps using WebViews expect the behavior of auto submitting multi-input forms.
    212213    if (fromImplicitSubmissionTrigger && (submissionTriggerCount == 1 || document().settings().allowMultiElementImplicitSubmission()))
    213         prepareForSubmission(event);
     214        submitIfPossible(&event);
    214215}
    215216
     
    254255}
    255256
    256 void HTMLFormElement::prepareForSubmission(Event& event)
     257void HTMLFormElement::submitIfPossible(Event* event, HTMLFormControlElement* submitter, FormSubmissionTrigger trigger)
    257258{
    258259    if (!isConnected())
     
    269270
    270271    if (shouldValidate) {
    271         auto submitElement = findSubmitButton(&event);
     272        auto submitElement = makeRefPtr(submitter ? submitter : findSubmitter(event));
    272273        if (submitElement && submitElement->formNoValidate())
    273274            shouldValidate = false;
     
    280281    }
    281282
    282     auto targetFrame = frame->loader().findFrameForNavigation(effectiveTarget(&event), &document());
     283    auto targetFrame = frame->loader().findFrameForNavigation(effectiveTarget(event, submitter), &document());
    283284    if (!targetFrame)
    284285        targetFrame = frame.get();
     
    298299
    299300    if (m_shouldSubmit)
    300         submit(&event, true, true, NotSubmittedByJavaScript);
     301        submit(event, true, !submitter, trigger, submitter);
    301302}
    302303
     
    309310{
    310311    submit(nullptr, false, UserGestureIndicator::processingUserGesture(), SubmittedByJavaScript);
     312}
     313
     314ExceptionOr<void> HTMLFormElement::requestSubmit(HTMLElement* submitter)
     315{
     316    // Update layout before processing form actions in case the style changes
     317    // the form or button relationships.
     318    document().updateLayoutIgnorePendingStylesheets();
     319
     320    RefPtr<HTMLFormControlElement> control;
     321    if (submitter) {
     322        // https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
     323        if (!is<HTMLFormControlElement>(submitter))
     324            return Exception { TypeError };
     325        control = downcast<HTMLFormControlElement>(submitter);
     326        if (!control->isSubmitButton())
     327            return Exception { TypeError };
     328        if (control->form() != this)
     329            return Exception { NotFoundError };
     330    }
     331
     332    submitIfPossible(nullptr, control.get(), SubmittedByJavaScript);
     333    return { };
    311334}
    312335
     
    327350}
    328351
    329 void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger formSubmissionTrigger)
    330 {
    331     // The prepareForSubmission function also does this check, but we need to do it here
     352RefPtr<HTMLFormControlElement> HTMLFormElement::findSubmitButton(HTMLFormControlElement* submitter, bool needButtonActivation)
     353{
     354    if (submitter)
     355        return submitter;
     356    if (!needButtonActivation)
     357        return nullptr;
     358    RefPtr<HTMLFormControlElement> firstSuccessfulSubmitButton;
     359    for (auto& associatedElement : m_associatedElements) {
     360        if (!is<HTMLFormControlElement>(*associatedElement))
     361            continue;
     362        auto& control = downcast<HTMLFormControlElement>(*associatedElement);
     363        if (control.isActivatedSubmit())
     364            return nullptr;
     365        if (!firstSuccessfulSubmitButton && control.isSuccessfulSubmitButton())
     366            firstSuccessfulSubmitButton = &control;
     367    }
     368    return firstSuccessfulSubmitButton;
     369}
     370
     371void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger trigger, HTMLFormControlElement* submitter)
     372{
     373    // The submitIfPossible function also does this check, but we need to do it here
    332374    // too, since there are some code paths that bypass that function.
    333375    if (!isConnected())
     
    347389    m_wasUserSubmitted = processingUserGesture;
    348390
    349     RefPtr<HTMLFormControlElement> firstSuccessfulSubmitButton;
    350     bool needButtonActivation = activateSubmitButton; // do we need to activate a submit button?
    351 
    352     for (auto& associatedElement : m_associatedElements) {
    353         if (!is<HTMLFormControlElement>(*associatedElement))
    354             continue;
    355         if (needButtonActivation) {
    356             HTMLFormControlElement& control = downcast<HTMLFormControlElement>(*associatedElement);
    357             if (control.isActivatedSubmit())
    358                 needButtonActivation = false;
    359             else if (!firstSuccessfulSubmitButton && control.isSuccessfulSubmitButton())
    360                 firstSuccessfulSubmitButton = &control;
    361         }
    362     }
    363 
    364     if (needButtonActivation && firstSuccessfulSubmitButton)
     391    auto firstSuccessfulSubmitButton = findSubmitButton(submitter, activateSubmitButton);
     392    if (firstSuccessfulSubmitButton)
    365393        firstSuccessfulSubmitButton->setActivatedSubmit(true);
    366394
     
    368396
    369397    auto shouldLockHistory = processingUserGesture ? LockHistory::No : LockHistory::Yes;
    370     auto formSubmission = FormSubmission::create(*this, m_attributes, event, shouldLockHistory, formSubmissionTrigger);
     398    auto formSubmission = FormSubmission::create(*this, submitter, m_attributes, event, shouldLockHistory, trigger);
    371399    if (m_plannedFormSubmission)
    372400        m_plannedFormSubmission->cancel();
     
    386414    frame->loader().submitForm(WTFMove(formSubmission));
    387415
    388     if (needButtonActivation && firstSuccessfulSubmitButton)
     416    if (firstSuccessfulSubmitButton)
    389417        firstSuccessfulSubmitButton->setActivatedSubmit(false);
    390418
     
    683711}
    684712
    685 String HTMLFormElement::effectiveTarget(const Event* event) const
    686 {
    687     if (auto* submitButton = findSubmitButton(event)) {
    688         auto targetValue = submitButton->attributeWithoutSynchronization(formtargetAttr);
     713String HTMLFormElement::effectiveTarget(const Event* event, HTMLFormControlElement* overrideSubmitter) const
     714{
     715    if (auto submitter = makeRefPtr(overrideSubmitter ? overrideSubmitter : findSubmitter(event))) {
     716        auto targetValue = submitter->attributeWithoutSynchronization(formtargetAttr);
    689717        if (!targetValue.isNull())
    690718            return targetValue;
     
    703731}
    704732
    705 HTMLFormControlElement* HTMLFormElement::findSubmitButton(const Event* event) const
     733HTMLFormControlElement* HTMLFormElement::findSubmitter(const Event* event) const
    706734{
    707735    if (!event || !is<Node>(event->target()))
     
    777805
    778806    // Update layout before processing form actions in case the style changes
    779     // the Form or button relationships.
     807    // the form or button relationships.
    780808    document().updateLayoutIgnorePendingStylesheets();
    781809
  • trunk/Source/WebCore/html/HTMLFormElement.h

    r273622 r277257  
    7878    void removeImgElement(HTMLImageElement*);
    7979
    80     void prepareForSubmission(Event&); // FIXME: This function doesn't only prepare, it sometimes calls submit() itself.
     80    void submitIfPossible(Event*, HTMLFormControlElement* = nullptr, FormSubmissionTrigger = NotSubmittedByJavaScript);
    8181    WEBCORE_EXPORT void submit();
    8282    void submitFromJavaScript();
     83    ExceptionOr<void> requestSubmit(HTMLElement* submitter);
    8384    WEBCORE_EXPORT void reset();
    8485
     
    102103
    103104    String target() const final;
    104     String effectiveTarget(const Event*) const;
     105    String effectiveTarget(const Event*, HTMLFormControlElement* submitter) const;
    105106
    106107    bool wasUserSubmitted() const;
    107108
    108     HTMLFormControlElement* findSubmitButton(const Event*) const;
     109    HTMLFormControlElement* findSubmitter(const Event*) const;
    109110
    110111    HTMLFormControlElement* defaultButton() const;
     
    141142    void copyNonAttributePropertiesFromElement(const Element&) final;
    142143
    143     void submit(Event*, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger);
     144    void submit(Event*, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger, HTMLFormControlElement* submitter = nullptr);
    144145
    145146    unsigned formElementIndexWithFormAttribute(Element*, unsigned rangeStart, unsigned rangeEnd);
     
    164165
    165166    void resetAssociatedFormControlElements();
     167
     168    RefPtr<HTMLFormControlElement> findSubmitButton(HTMLFormControlElement* submitter, bool needButtonActivation);
    166169
    167170    FormSubmission::Attributes m_attributes;
  • trunk/Source/WebCore/html/HTMLFormElement.idl

    r267813 r277257  
    4141
    4242    [ImplementedAs=submitFromJavaScript] undefined submit();
     43    [EnabledBySetting=RequestSubmit] undefined requestSubmit(optional HTMLElement? submitter);
    4344    [CEReactions=NotNeeded] undefined reset();
    4445    boolean checkValidity();
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r277001 r277257  
    123123    bool isImageButton() const;
    124124    WEBCORE_EXPORT bool isNumberField() const;
    125     bool isSubmitButton() const;
     125    bool isSubmitButton() const final;
    126126    WEBCORE_EXPORT bool isTelephoneField() const;
    127127    WEBCORE_EXPORT bool isURLField() const;
  • trunk/Source/WebCore/html/ImageInputType.cpp

    r272180 r277257  
    104104
    105105    if (auto currentForm = protectedElement->form())
    106         currentForm->prepareForSubmission(event); // Event handlers can run.
     106        currentForm->submitIfPossible(&event); // Event handlers can run.
    107107
    108108    protectedElement->setActivatedSubmit(false);
  • trunk/Source/WebCore/html/ImageInputType.h

    r272180 r277257  
    5757    unsigned width() const final;
    5858
    59     IntPoint m_clickLocation; // Valid only during HTMLFormElement::prepareForSubmission().
     59    IntPoint m_clickLocation; // Valid only during HTMLFormElement::submitIfPossible().
    6060};
    6161
  • trunk/Source/WebCore/html/InputType.h

    r273049 r277257  
    178178    bool isRangeControl() const { return m_type == Type::Range; }
    179179    bool isSearchField() const { return m_type == Type::Search; }
    180     bool isSubmitButton() const { return m_type == Type::Submit; }
     180    bool isSubmitButton() const { return m_type == Type::Submit || m_type == Type::Image; }
    181181    bool isTelephoneField() const { return m_type == Type::Telephone; }
    182182    bool isTimeField() const { return m_type == Type::Time; }
  • trunk/Source/WebCore/html/SubmitInputType.cpp

    r272097 r277257  
    7575
    7676    protectedElement->setActivatedSubmit(true);
    77     if (auto currentForm = protectedElement->form())
    78         currentForm->prepareForSubmission(event); // Event handlers can run.
     77    if (auto currentForm = makeRefPtr(protectedElement->form()))
     78        currentForm->submitIfPossible(&event); // Event handlers can run.
    7979    protectedElement->setActivatedSubmit(false);
    8080    event.setDefaultHandled();
  • trunk/Source/WebCore/loader/FormSubmission.cpp

    r261036 r277257  
    143143}
    144144
    145 Ref<FormSubmission> FormSubmission::create(HTMLFormElement& form, const Attributes& attributes, Event* event, LockHistory lockHistory, FormSubmissionTrigger trigger)
     145Ref<FormSubmission> FormSubmission::create(HTMLFormElement& form, HTMLFormControlElement* overrideSubmitter, const Attributes& attributes, Event* event, LockHistory lockHistory, FormSubmissionTrigger trigger)
    146146{
    147147    auto copiedAttributes = attributes;
    148148
    149     if (auto* submitButton = form.findSubmitButton(event)) {
     149    auto submitter = makeRefPtr(overrideSubmitter ? overrideSubmitter : form.findSubmitter(event));
     150    if (submitter) {
    150151        AtomString attributeValue;
    151         if (!(attributeValue = submitButton->attributeWithoutSynchronization(formactionAttr)).isNull())
     152        if (!(attributeValue = submitter->attributeWithoutSynchronization(formactionAttr)).isNull())
    152153            copiedAttributes.parseAction(attributeValue);
    153         if (!(attributeValue = submitButton->attributeWithoutSynchronization(formenctypeAttr)).isNull())
     154        if (!(attributeValue = submitter->attributeWithoutSynchronization(formenctypeAttr)).isNull())
    154155            copiedAttributes.updateEncodingType(attributeValue);
    155         if (!(attributeValue = submitButton->attributeWithoutSynchronization(formmethodAttr)).isNull())
     156        if (!(attributeValue = submitter->attributeWithoutSynchronization(formmethodAttr)).isNull())
    156157            copiedAttributes.updateMethodType(attributeValue);
    157         if (!(attributeValue = submitButton->attributeWithoutSynchronization(formtargetAttr)).isNull())
     158        if (!(attributeValue = submitter->attributeWithoutSynchronization(formtargetAttr)).isNull())
    158159            copiedAttributes.setTarget(attributeValue);
    159160    }
     
    215216    auto formState = FormState::create(form, WTFMove(formValues), document, trigger);
    216217
    217     return adoptRef(*new FormSubmission(copiedAttributes.method(), actionURL, form.effectiveTarget(event), encodingType, WTFMove(formState), formData.releaseNonNull(), boundary, lockHistory, event));
     218    return adoptRef(*new FormSubmission(copiedAttributes.method(), actionURL, form.effectiveTarget(event, submitter.get()), encodingType, WTFMove(formState), formData.releaseNonNull(), boundary, lockHistory, event));
    218219}
    219220
  • trunk/Source/WebCore/loader/FormSubmission.h

    r253799 r277257  
    4141class FormData;
    4242class FrameLoadRequest;
     43class HTMLFormControlElement;
    4344
    4445class FormSubmission : public RefCounted<FormSubmission>, public CanMakeWeakPtr<FormSubmission> {
     
    7677    };
    7778
    78     static Ref<FormSubmission> create(HTMLFormElement&, const Attributes&, Event*, LockHistory, FormSubmissionTrigger);
     79    static Ref<FormSubmission> create(HTMLFormElement&, HTMLFormControlElement* overrideSubmitter, const Attributes&, Event*, LockHistory, FormSubmissionTrigger);
    7980
    8081    void populateFrameLoadRequest(FrameLoadRequest&);
Note: See TracChangeset for help on using the changeset viewer.