Open Bug 1909539 Opened 4 months ago Updated 3 months ago

preventDefault() in "beforeinput" event handler doesn't avoid form submission

Categories

(Core :: DOM: Events, defect)

Firefox 128
defect

Tracking

()

People

(Reporter: vlakoff, Unassigned)

References

()

Details

(Keywords: parity-chrome)

Steps to reproduce:

Go to a page containing a form, and add a "beforeinput" event handler aiming to avoid the form submission if the Enter key is pressed.

As an example:

  1. Go to https://en.wikipedia.org/w/index.php?title=Wikipedia:Sandbox&action=edit
  2. Execute the following JS snippet:

document.getElementById('wpSummary').addEventListener('beforeinput', function (e) {
if (e.inputType === 'insertLineBreak') {
e.preventDefault();
alert('Blocked accidental publication with the Enter key!');
}
});

  1. Put caret in the "Edit summary" text input box.
  2. Press Enter.

Actual results:

  1. The alert is displayed, as expected. (this step is not mandatory, the alert may be removed from the testcase)
  2. After the alert is closed, the form gets submitted!

Expected results:

  1. The alert is displayed.
  2. After the alert is closed, the form DOES NOT get submitted.

Additional notes:

  • Google Chrome doesn't have the issue, i.e. the form is not submitted.
  • Using keypress event instead (testing for e.key === 'Enter') works, it prevents the form submission.
Component: Untriaged → DOM: Events
Product: Firefox → Core

I made more tries:

  • preventDefault() does prevent inputting regular characters.
  • In a <textarea>, preventDefault() does prevent inputting a newline.

It is as if, when implementing preventDefault() in beforeinput event handlers, you oversought the fact that typing Enter in a <input type="text"> triggers the form submission.

I am able to reproduce on Debian using the latest nightly.
The cause appears to be that, for single-line text inputs, even if the beforeinput event is cancelled, the triggering keyboard event does not get disabled.

@masayuki: Since you tend to handle libeditor issues, you might be best equipped to know: Is this behaviour intentional?

Flags: needinfo?(masayuki)

Well, I did not do it intentionally, but I think our behavior must be correct.

The default action of beforeinput is defined as:

  • For contentEditable=typing editing hosts for inputTypes "insertCompositionText" and "deleteCompositionText": 'Update the DOM'.
  • For contentEditable="true" editing hosts for all inputTypes: 'Update the DOM'.
  • For EditContext editing hosts for EditContext-handled inputTypes: Handle input for EditContext given the editing host element.
  • None otherwise.

Surprisingly, <input> behavior is not defined by the Input Events spec, though (spec issue). Submitting the form with pressing Enter is a shortcut key of browsers, not an edit command of the builtin editors. So, the default action of beforeinput should be updating the value of <input> and <textarea>. Therefore, preventing only updating the value should be reasonable. (Anyway, submitting form should be prevented by submit event listener for handling all shortcuts.)

On the other hand, this is an interesting web-compat issue.

Flags: needinfo?(masayuki)
Severity: -- → S4
Keywords: parity-chrome
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Unspecified → All
Hardware: Unspecified → All

Safari also does not prevent the form submission.

Although I understand your opinion in the Chromium and the W3C tickets, I think the correct behavior should really be to prevent the form submission:

  • Users expect that preventDefault() does what is written on the tin: discards browser actions, as if the browser is no longer seeing the key input.
  • That's what keypress and keydown do. But the former is deprecated, and the latter is less adequate, being about physical keyboard.
  • Using a keypress event (which is the recommended one), if removing the preventDefault() way, there would be no other way to avoid form submission…
You need to log in before you can comment on or make changes to this bug.