Commit 745e1b45 authored by Joshua Bell's avatar Joshua Bell Committed by Commit Bot

<input type=file webkitdirectory>: Launch picker on Enter keyup

Avoid key repeat triggering an unintentional commit of the subsequent
dialog by launching the picker on the Enter keyup event rather than on
keydown.

Bug: 637098
Change-Id: Ia327a7a9f92c34fd3fcdf971d8c21a5ce744254b
Reviewed-on: https://chromium-review.googlesource.com/814916
Commit-Queue: Joshua Bell <jsbell@chromium.org>
Reviewed-by: default avatarChris Palmer <palmer@chromium.org>
Reviewed-by: default avatarEmily Stark <estark@chromium.org>
Reviewed-by: default avatarKeishi Hattori <keishi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523507}
parent a6098813
......@@ -39,7 +39,7 @@ function logEvent(event)
debug(event.type + ': ' + targetDescription(event.target));
}
var keys = ['\r', ' '];
var keys = ['Enter', ' '];
var keyNames = ['Enter', 'U+0020'];
var tagNames = ['button', 'input'];
......
Mock: Opening a file chooser.
Ensure pressing Enter key with focus on an INPUT element with TYPE=FILE and WEBKITDIRECTORY still launches a file chooser if preventDefault() is called on the 'keypress' event. Automated test passes if 'Opening a file chooser' was logged.
keypress prevented
<!DOCTYPE html>
<title>INPUT TYPE=FILE WEBKITDIRECTORY and key events - Enter keypress prevented</title>
<p>
Ensure pressing Enter key with focus on an INPUT element with
TYPE=FILE and WEBKITDIRECTORY still launches a file chooser if
preventDefault() is called on the 'keypress' event. Automated test
passes if 'Opening a file chooser' was logged.
</p>
<pre id=console></pre>
<input type="file" webkitdirectory>
<script>
document.querySelector('input').onkeypress = e => {
document.querySelector('#console').innerText = `${e.type} prevented`;
e.preventDefault();
};
if (testRunner && eventSender) {
testRunner.dumpAsText();
document.querySelector('input').focus();
// Despite the name, 'keyDown' simulates a full down/press/up sequence.
eventSender.keyDown('Enter', []);
}
</script>
Ensure pressing Enter key with focus on an INPUT element with TYPE=FILE and WEBKITDIRECTORY does not launch a file chooser if preventDefault() is called on the 'keyup' event. Automated test passes if 'Opening a file chooser' was not logged.
keyup prevented
<!DOCTYPE html>
<title>INPUT TYPE=FILE WEBKITDIRECTORY and key events - Enter keyup prevented</title>
<p>
Ensure pressing Enter key with focus on an INPUT element with
TYPE=FILE and WEBKITDIRECTORY does <b>not</b> launch a file chooser
if preventDefault() is called on the 'keyup' event. Automated test
passes if 'Opening a file chooser' was <b>not</b> logged.
</p>
<pre id=console></pre>
<input type="file" webkitdirectory>
<script>
document.querySelector('input').onkeyup = e => {
document.querySelector('#console').innerText = `${e.type} prevented`;
e.preventDefault();
};
if (testRunner && eventSender) {
testRunner.dumpAsText();
document.querySelector('input').focus();
// Despite the name, 'keyDown' simulates a full down/press/up sequence.
eventSender.keyDown('Enter', []);
}
</script>
......@@ -26,6 +26,7 @@
#include "core/css/StyleChangeReason.h"
#include "core/dom/ShadowRoot.h"
#include "core/dom/events/Event.h"
#include "core/events/KeyboardEvent.h"
#include "core/fileapi/File.h"
#include "core/fileapi/FileList.h"
#include "core/frame/UseCounter.h"
......@@ -420,4 +421,30 @@ void FileInputType::CopyNonAttributeProperties(const HTMLInputElement& source) {
file_list_->Append(source_list->item(i)->Clone());
}
void FileInputType::HandleKeypressEvent(KeyboardEvent* event) {
if (GetElement().FastHasAttribute(webkitdirectoryAttr)) {
// Override to invoke the action on Enter key up (not press) to avoid
// repeats committing the file chooser.
const String& key = event->key();
if (key == "Enter") {
event->SetDefaultHandled();
return;
}
}
KeyboardClickableInputTypeView::HandleKeypressEvent(event);
}
void FileInputType::HandleKeyupEvent(KeyboardEvent* event) {
if (GetElement().FastHasAttribute(webkitdirectoryAttr)) {
// Override to invoke the action on Enter key up (not press) to avoid
// repeats committing the file chooser.
if (event->key() == "Enter") {
GetElement().DispatchSimulatedClick(event);
event->SetDefaultHandled();
return;
}
}
KeyboardClickableInputTypeView::HandleKeyupEvent(event);
}
} // namespace blink
......@@ -91,6 +91,10 @@ class CORE_EXPORT FileInputType final : public InputType,
String DefaultToolTip(const InputTypeView&) const override;
void CopyNonAttributeProperties(const HTMLInputElement&) override;
// KeyboardClickableInputTypeView overrides.
void HandleKeypressEvent(KeyboardEvent*) override;
void HandleKeyupEvent(KeyboardEvent*) override;
// FileChooserClient implementation.
void FilesChosen(const Vector<FileChooserFileInfo>&) override;
......
......@@ -49,13 +49,13 @@ void KeyboardClickableInputTypeView::HandleKeydownEvent(KeyboardEvent* event) {
}
void KeyboardClickableInputTypeView::HandleKeypressEvent(KeyboardEvent* event) {
int char_code = event->charCode();
if (char_code == '\r') {
const String& key = event->key();
if (key == "Enter") {
GetElement().DispatchSimulatedClick(event);
event->SetDefaultHandled();
return;
}
if (char_code == ' ') {
if (key == " ") {
// Prevent scrolling down the page.
event->SetDefaultHandled();
}
......
......@@ -42,7 +42,7 @@ class CORE_EXPORT KeyboardClickableInputTypeView : public InputTypeView {
KeyboardClickableInputTypeView(HTMLInputElement& element)
: InputTypeView(element) {}
private:
protected:
void HandleKeydownEvent(KeyboardEvent*) override;
void HandleKeypressEvent(KeyboardEvent*) override;
void HandleKeyupEvent(KeyboardEvent*) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment