showPicker: Fix isMutable behaviour

This CL makes sure showPicker throws an error when the input element
is not mutable. Wit this CL, the type of the input is taken into account
when determining the mutability state of the element.

Spec: https://html.spec.whatwg.org/multipage/input.html#dom-input-showpicker
Test: http://wpt.live/html/semantics/forms/the-input-element/show-picker-disabled-readonly.html
Bug: 1365302
Change-Id: Ie368287d347eebf664d224a863c90a281a540bd5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3904381
Commit-Queue: Fr <beaufort.francois@gmail.com>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1048736}
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index 1b2ed29..68d196c 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -2265,6 +2265,12 @@
   }
 }
 
+// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-fe-mutable
+bool HTMLInputElement::isMutable() {
+  return !IsDisabledFormControl() &&
+         !(input_type_->SupportsReadOnly() && IsReadOnly());
+}
+
 // Show a browser picker for this input element.
 // https://html.spec.whatwg.org/multipage/input.html#dom-input-showpicker
 void HTMLInputElement::showPicker(ExceptionState& exception_state) {
@@ -2285,7 +2291,7 @@
     }
   }
 
-  if (IsDisabledOrReadOnly()) {
+  if (!isMutable()) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kInvalidStateError,
         "HTMLInputElement::showPicker() cannot be used on immutable controls.");
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h
index 1505b2e..2d47a8f3 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -368,6 +368,7 @@
     form_element_pii_type_ = form_element_pii_type;
   }
 
+  bool isMutable();
   void showPicker(ExceptionState&);
 
  protected:
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/show-picker-disabled-readonly-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/show-picker-disabled-readonly-expected.txt
deleted file mode 100644
index ca2ba34..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/show-picker-disabled-readonly-expected.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-This is a testharness.js-based test.
-PASS input[type=button] showPicker() throws when disabled
-PASS input[type=checkbox] showPicker() throws when disabled
-PASS input[type=color] showPicker() throws when disabled
-PASS input[type=date] showPicker() throws when disabled
-PASS input[type=datetime-local] showPicker() throws when disabled
-PASS input[type=email] showPicker() throws when disabled
-PASS input[type=file] showPicker() throws when disabled
-PASS input[type=hidden] showPicker() throws when disabled
-PASS input[type=image] showPicker() throws when disabled
-PASS input[type=month] showPicker() throws when disabled
-PASS input[type=number] showPicker() throws when disabled
-PASS input[type=password] showPicker() throws when disabled
-PASS input[type=radio] showPicker() throws when disabled
-PASS input[type=range] showPicker() throws when disabled
-PASS input[type=reset] showPicker() throws when disabled
-PASS input[type=search] showPicker() throws when disabled
-PASS input[type=submit] showPicker() throws when disabled
-PASS input[type=tel] showPicker() throws when disabled
-PASS input[type=text] showPicker() throws when disabled
-PASS input[type=time] showPicker() throws when disabled
-PASS input[type=url] showPicker() throws when disabled
-PASS input[type=week] showPicker() throws when disabled
-FAIL input[type=button] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-FAIL input[type=checkbox] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-FAIL input[type=color] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-PASS input[type=date] showPicker() throws when readonly
-PASS input[type=datetime-local] showPicker() throws when readonly
-PASS input[type=email] showPicker() throws when readonly
-FAIL input[type=file] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-FAIL input[type=hidden] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-FAIL input[type=image] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-PASS input[type=month] showPicker() throws when readonly
-PASS input[type=number] showPicker() throws when readonly
-PASS input[type=password] showPicker() throws when readonly
-FAIL input[type=radio] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-FAIL input[type=range] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-FAIL input[type=reset] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-PASS input[type=search] showPicker() throws when readonly
-FAIL input[type=submit] showPicker() doesn't throw when readonly assert_throws_dom: function "() => { input.showPicker(); }" threw object "InvalidStateError: Failed to execute 'showPicker' on 'HTMLInputElement': HTMLInputElement::showPicker() cannot be used on immutable controls." that is not a DOMException NotAllowedError: property "code" is equal to 11, expected 0
-PASS input[type=tel] showPicker() throws when readonly
-PASS input[type=text] showPicker() throws when readonly
-PASS input[type=time] showPicker() throws when readonly
-PASS input[type=url] showPicker() throws when readonly
-PASS input[type=week] showPicker() throws when readonly
-Harness: the test ran to completion.
-