mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibWeb/HTML: Correctly compute whether element is mutable
This adapts the implementation of `is_mutable` to align more closely with the spec. Specifically, it is now also taken into account whether the element is enabled.
This commit is contained in:
parent
1228063a85
commit
cac2ee41b9
|
|
@ -145,6 +145,9 @@ public:
|
|||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-setcustomvalidity
|
||||
void set_custom_validity(String& error);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#mutability
|
||||
virtual bool is_mutable() const { return true; }
|
||||
|
||||
protected:
|
||||
FormAssociatedElement() = default;
|
||||
virtual ~FormAssociatedElement() = default;
|
||||
|
|
@ -220,9 +223,6 @@ public:
|
|||
bool has_scheduled_selectionchange_event() const { return m_has_scheduled_selectionchange_event; }
|
||||
void set_scheduled_selectionchange_event(bool value) { m_has_scheduled_selectionchange_event = value; }
|
||||
|
||||
bool is_mutable() const { return m_is_mutable; }
|
||||
void set_is_mutable(bool is_mutable) { m_is_mutable = is_mutable; }
|
||||
|
||||
virtual void did_edit_text_node() = 0;
|
||||
|
||||
virtual GC::Ptr<DOM::Text> form_associated_element_to_text_node() = 0;
|
||||
|
|
@ -260,9 +260,6 @@ private:
|
|||
|
||||
// https://w3c.github.io/selection-api/#dfn-has-scheduled-selectionchange-event
|
||||
bool m_has_scheduled_selectionchange_event { false };
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#mutability
|
||||
bool m_is_mutable { true };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -893,13 +893,6 @@ void HTMLInputElement::handle_maxlength_attribute()
|
|||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#attr-input-readonly
|
||||
void HTMLInputElement::handle_readonly_attribute(Optional<String> const& maybe_value)
|
||||
{
|
||||
// The readonly attribute is a boolean attribute that controls whether or not the user can edit the form control. When specified, the element is not mutable.
|
||||
set_is_mutable(!maybe_value.has_value() || !is_allowed_to_be_readonly(m_type));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#the-input-element:attr-input-placeholder-3
|
||||
static bool is_allowed_to_have_placeholder(HTML::HTMLInputElement::TypeAttributeState state)
|
||||
{
|
||||
|
|
@ -1066,7 +1059,6 @@ void HTMLInputElement::create_text_input_shadow_tree()
|
|||
MUST(element->append_child(*m_inner_text_element));
|
||||
|
||||
m_text_node = realm().create<DOM::Text>(document(), move(initial_value));
|
||||
handle_readonly_attribute(attribute(HTML::AttributeNames::readonly));
|
||||
if (type_state() == TypeAttributeState::Password)
|
||||
m_text_node->set_is_password_input({}, true);
|
||||
handle_maxlength_attribute();
|
||||
|
|
@ -1414,8 +1406,6 @@ void HTMLInputElement::form_associated_element_attribute_changed(FlyString const
|
|||
m_placeholder_text_node->set_data(Utf16String::from_utf8(placeholder()));
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
} else if (name == HTML::AttributeNames::readonly) {
|
||||
handle_readonly_attribute(value);
|
||||
} else if (name == HTML::AttributeNames::src) {
|
||||
handle_src_attribute(value.value_or({})).release_value_but_fixme_should_propagate_errors();
|
||||
} else if (name == HTML::AttributeNames::alt) {
|
||||
|
|
@ -3563,4 +3553,16 @@ void HTMLInputElement::set_is_open(bool is_open)
|
|||
invalidate_style(DOM::StyleInvalidationReason::HTMLInputElementSetIsOpen);
|
||||
}
|
||||
|
||||
bool HTMLInputElement::is_mutable() const
|
||||
{
|
||||
return
|
||||
// https://html.spec.whatwg.org/multipage/input.html#the-input-element:concept-fe-mutable-3
|
||||
// A select element that is not disabled is mutable.
|
||||
enabled()
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#the-readonly-attribute:concept-fe-mutable
|
||||
// The readonly attribute is a boolean attribute that controls whether or not the user can edit the form control. When specified, the element is not mutable.
|
||||
&& !(has_attribute(AttributeNames::readonly) && is_allowed_to_be_readonly(m_type));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,6 +252,8 @@ public:
|
|||
virtual bool suffering_from_a_step_mismatch() const override;
|
||||
virtual bool suffering_from_bad_input() const override;
|
||||
|
||||
virtual bool is_mutable() const override;
|
||||
|
||||
private:
|
||||
HTMLInputElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
|
|
@ -320,7 +322,6 @@ private:
|
|||
void set_checked_within_group();
|
||||
|
||||
void handle_maxlength_attribute();
|
||||
void handle_readonly_attribute(Optional<String> const& value);
|
||||
WebIDL::ExceptionOr<void> handle_src_attribute(String const& value);
|
||||
|
||||
void user_interaction_did_change_input_value();
|
||||
|
|
|
|||
|
|
@ -429,7 +429,7 @@ void HTMLSelectElement::show_the_picker_if_applicable()
|
|||
return;
|
||||
|
||||
// 2. If element is not mutable, then return.
|
||||
if (!enabled())
|
||||
if (!is_mutable())
|
||||
return;
|
||||
|
||||
// 3. Consume user activation given element's relevant global object.
|
||||
|
|
@ -494,7 +494,7 @@ WebIDL::ExceptionOr<void> HTMLSelectElement::show_picker()
|
|||
// The showPicker() method steps are:
|
||||
|
||||
// 1. If this is not mutable, then throw an "InvalidStateError" DOMException.
|
||||
if (!enabled())
|
||||
if (!is_mutable())
|
||||
return WebIDL::InvalidStateError::create(realm(), "Element is not mutable"_utf16);
|
||||
|
||||
// 2. If this's relevant settings object's origin is not same origin with this's relevant settings object's top-level origin,
|
||||
|
|
@ -740,4 +740,11 @@ bool HTMLSelectElement::suffering_from_being_missing() const
|
|||
return has_attribute(HTML::AttributeNames::required) && (selected_options->length() == 0 || (selected_options->length() == 1 && selected_options->item(0) == placeholder_label_option()));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element:concept-fe-mutable
|
||||
bool HTMLSelectElement::is_mutable() const
|
||||
{
|
||||
// A select element that is not disabled is mutable.
|
||||
return enabled();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ public:
|
|||
// https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element%3Asuffering-from-being-missing
|
||||
virtual bool suffering_from_being_missing() const override;
|
||||
|
||||
virtual bool is_mutable() const override;
|
||||
|
||||
private:
|
||||
HTMLSelectElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
|
|
|
|||
|
|
@ -376,7 +376,6 @@ void HTMLTextAreaElement::create_shadow_tree_if_needed()
|
|||
MUST(element->append_child(*m_inner_text_element));
|
||||
|
||||
m_text_node = realm().create<DOM::Text>(document(), Utf16String {});
|
||||
handle_readonly_attribute(attribute(HTML::AttributeNames::readonly));
|
||||
// NOTE: If `children_changed()` was called before now, `m_raw_value` will hold the text content.
|
||||
// Otherwise, it will get filled in whenever that does get called.
|
||||
m_text_node->set_text_content(m_raw_value);
|
||||
|
|
@ -386,13 +385,6 @@ void HTMLTextAreaElement::create_shadow_tree_if_needed()
|
|||
update_placeholder_visibility();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#attr-input-readonly
|
||||
void HTMLTextAreaElement::handle_readonly_attribute(Optional<String> const& maybe_value)
|
||||
{
|
||||
// The readonly attribute is a boolean attribute that controls whether or not the user can edit the form control. When specified, the element is not mutable.
|
||||
set_is_mutable(!maybe_value.has_value());
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-maxlength
|
||||
void HTMLTextAreaElement::handle_maxlength_attribute()
|
||||
{
|
||||
|
|
@ -442,8 +434,6 @@ void HTMLTextAreaElement::form_associated_element_attribute_changed(FlyString co
|
|||
if (name == HTML::AttributeNames::placeholder) {
|
||||
if (m_placeholder_text_node)
|
||||
m_placeholder_text_node->set_data(Utf16String::from_utf8(value.value_or(String {})));
|
||||
} else if (name == HTML::AttributeNames::readonly) {
|
||||
handle_readonly_attribute(value);
|
||||
} else if (name == HTML::AttributeNames::maxlength) {
|
||||
handle_maxlength_attribute();
|
||||
}
|
||||
|
|
@ -489,4 +479,11 @@ bool HTMLTextAreaElement::suffering_from_being_missing() const
|
|||
return has_attribute(HTML::AttributeNames::required) && is_mutable() && value().is_empty();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element:concept-fe-mutable
|
||||
bool HTMLTextAreaElement::is_mutable() const
|
||||
{
|
||||
// A textarea element is mutable if it is neither disabled nor has a readonly attribute specified.
|
||||
return enabled() && !has_attribute(AttributeNames::readonly);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,6 +134,9 @@ public:
|
|||
// https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element%3Asuffering-from-being-missing
|
||||
virtual bool suffering_from_being_missing() const override;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element:concept-fe-mutable
|
||||
virtual bool is_mutable() const override;
|
||||
|
||||
private:
|
||||
HTMLTextAreaElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
|
|
@ -147,7 +150,6 @@ private:
|
|||
|
||||
void create_shadow_tree_if_needed();
|
||||
|
||||
void handle_readonly_attribute(Optional<String> const& value);
|
||||
void handle_maxlength_attribute();
|
||||
|
||||
void queue_firing_input_event();
|
||||
|
|
|
|||
|
|
@ -2,70 +2,70 @@ Harness status: OK
|
|||
|
||||
Found 78 tests
|
||||
|
||||
46 Pass
|
||||
32 Fail
|
||||
77 Pass
|
||||
1 Fail
|
||||
Pass [INPUT in TEXT status] The required attribute is not set
|
||||
Pass [INPUT in TEXT status] The value is not empty and required is true
|
||||
Fail [INPUT in TEXT status] The value is empty and required is true
|
||||
Pass [INPUT in TEXT status] The value is empty and required is true
|
||||
Pass [INPUT in SEARCH status] The required attribute is not set
|
||||
Pass [INPUT in SEARCH status] The value is not empty and required is true
|
||||
Fail [INPUT in SEARCH status] The value is empty and required is true
|
||||
Pass [INPUT in SEARCH status] The value is empty and required is true
|
||||
Pass [INPUT in TEL status] The required attribute is not set
|
||||
Pass [INPUT in TEL status] The value is not empty and required is true
|
||||
Fail [INPUT in TEL status] The value is empty and required is true
|
||||
Pass [INPUT in TEL status] The value is empty and required is true
|
||||
Pass [INPUT in URL status] The required attribute is not set
|
||||
Pass [INPUT in URL status] The value is not empty and required is true
|
||||
Fail [INPUT in URL status] The value is empty and required is true
|
||||
Pass [INPUT in URL status] The value is empty and required is true
|
||||
Pass [INPUT in EMAIL status] The required attribute is not set
|
||||
Pass [INPUT in EMAIL status] The value is not empty and required is true
|
||||
Fail [INPUT in EMAIL status] The value is empty and required is true
|
||||
Pass [INPUT in EMAIL status] The value is empty and required is true
|
||||
Pass [INPUT in PASSWORD status] The required attribute is not set
|
||||
Pass [INPUT in PASSWORD status] The value is not empty and required is true
|
||||
Fail [INPUT in PASSWORD status] The value is empty and required is true
|
||||
Pass [INPUT in PASSWORD status] The value is empty and required is true
|
||||
Pass [INPUT in DATETIME-LOCAL status] The required attribute is not set
|
||||
Pass [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10T12:00:00)
|
||||
Pass [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00)
|
||||
Pass [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14T12:00:00.001)
|
||||
Fail [INPUT in DATETIME-LOCAL status] The value attribute is a number(1234567)
|
||||
Fail [INPUT in DATETIME-LOCAL status] The value attribute is a Date object
|
||||
Fail [INPUT in DATETIME-LOCAL status] Invalid local date and time string(1979-10-99 99:99)
|
||||
Pass [INPUT in DATETIME-LOCAL status] The value attribute is a number(1234567)
|
||||
Pass [INPUT in DATETIME-LOCAL status] The value attribute is a Date object
|
||||
Pass [INPUT in DATETIME-LOCAL status] Invalid local date and time string(1979-10-99 99:99)
|
||||
Pass [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00)
|
||||
Fail [INPUT in DATETIME-LOCAL status] Invalid local date and time string(2001-12-21 12:00)-two white space
|
||||
Fail [INPUT in DATETIME-LOCAL status] the value attribute is a string(abc)
|
||||
Fail [INPUT in DATETIME-LOCAL status] The value attribute is empty string
|
||||
Pass [INPUT in DATETIME-LOCAL status] Invalid local date and time string(2001-12-21 12:00)-two white space
|
||||
Pass [INPUT in DATETIME-LOCAL status] the value attribute is a string(abc)
|
||||
Pass [INPUT in DATETIME-LOCAL status] The value attribute is empty string
|
||||
Pass [INPUT in DATE status] The required attribute is not set
|
||||
Pass [INPUT in DATE status] Valid date string(2000-12-10)
|
||||
Pass [INPUT in DATE status] Valid date string(9999-01-01)
|
||||
Fail [INPUT in DATE status] The value attribute is a number(1234567)
|
||||
Fail [INPUT in DATE status] The value attribute is a Date object
|
||||
Fail [INPUT in DATE status] Invalid date string(9999-99-99)
|
||||
Fail [INPUT in DATE status] Invalid date string(37-01-01)
|
||||
Fail [INPUT in DATE status] Invalid date string(2000/01/01)
|
||||
Fail [INPUT in DATE status] The value attribute is empty string
|
||||
Pass [INPUT in DATE status] The value attribute is a number(1234567)
|
||||
Pass [INPUT in DATE status] The value attribute is a Date object
|
||||
Pass [INPUT in DATE status] Invalid date string(9999-99-99)
|
||||
Pass [INPUT in DATE status] Invalid date string(37-01-01)
|
||||
Pass [INPUT in DATE status] Invalid date string(2000/01/01)
|
||||
Pass [INPUT in DATE status] The value attribute is empty string
|
||||
Pass [INPUT in TIME status] The required attribute is not set
|
||||
Pass [INPUT in TIME status] Validtime string(12:00:00)
|
||||
Pass [INPUT in TIME status] Validtime string(12:00)
|
||||
Pass [INPUT in TIME status] Valid time string(12:00:60.001)
|
||||
Pass [INPUT in TIME status] Valid time string(12:00:60.01)
|
||||
Pass [INPUT in TIME status] Valid time string(12:00:60.1)
|
||||
Fail [INPUT in TIME status] The value attribute is a number(1234567)
|
||||
Fail [INPUT in TIME status] The value attribute is a time object
|
||||
Fail [INPUT in TIME status] Invalid time string(25:00:00)
|
||||
Fail [INPUT in TIME status] Invalid time string(12:60:00)
|
||||
Fail [INPUT in TIME status] Invalid time string(12:00:60)
|
||||
Fail [INPUT in TIME status] Invalid time string(12:00:00:001)
|
||||
Fail [INPUT in TIME status] The value attribute is empty string
|
||||
Pass [INPUT in TIME status] The value attribute is a number(1234567)
|
||||
Pass [INPUT in TIME status] The value attribute is a time object
|
||||
Pass [INPUT in TIME status] Invalid time string(25:00:00)
|
||||
Pass [INPUT in TIME status] Invalid time string(12:60:00)
|
||||
Pass [INPUT in TIME status] Invalid time string(12:00:60)
|
||||
Pass [INPUT in TIME status] Invalid time string(12:00:00:001)
|
||||
Pass [INPUT in TIME status] The value attribute is empty string
|
||||
Pass [INPUT in NUMBER status] The required attribute is not set
|
||||
Pass [INPUT in NUMBER status] Value is an integer with a leading symbol '+'
|
||||
Pass [INPUT in NUMBER status] Value is a number with a '-' symbol
|
||||
Pass [INPUT in NUMBER status] Value is a number in scientific notation form(e is in lowercase)
|
||||
Pass [INPUT in NUMBER status] Value is a number in scientific notation form(E is in uppercase)
|
||||
Pass [INPUT in NUMBER status] Value is -0
|
||||
Fail [INPUT in NUMBER status] Value is a number with some white spaces
|
||||
Fail [INPUT in NUMBER status] Value is Math.pow(2, 1024)
|
||||
Fail [INPUT in NUMBER status] Value is Math.pow(-2, 1024)
|
||||
Fail [INPUT in NUMBER status] Value is a string that cannot be converted to a number
|
||||
Fail [INPUT in NUMBER status] The value attribute is empty string
|
||||
Pass [INPUT in NUMBER status] Value is a number with some white spaces
|
||||
Pass [INPUT in NUMBER status] Value is Math.pow(2, 1024)
|
||||
Pass [INPUT in NUMBER status] Value is Math.pow(-2, 1024)
|
||||
Pass [INPUT in NUMBER status] Value is a string that cannot be converted to a number
|
||||
Pass [INPUT in NUMBER status] The value attribute is empty string
|
||||
Pass [INPUT in CHECKBOX status] The required attribute is not set
|
||||
Pass [INPUT in CHECKBOX status] The checked attribute is true
|
||||
Pass [INPUT in CHECKBOX status] The checked attribute is false
|
||||
|
|
@ -80,5 +80,5 @@ Pass [select] Selected the option with value equals to 1
|
|||
Pass [select] Selected the option with value equals to empty
|
||||
Pass [textarea] The required attribute is not set
|
||||
Pass [textarea] The value is not empty
|
||||
Fail [textarea] The value is empty
|
||||
Pass [textarea] The value is empty
|
||||
Fail validationMessage should return empty string when willValidate is false and valueMissing is true
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 44 tests
|
||||
|
||||
44 Pass
|
||||
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
|
||||
Pass input[type=button] showPicker() doesn't throw when readonly
|
||||
Pass input[type=checkbox] showPicker() doesn't throw when readonly
|
||||
Pass input[type=color] showPicker() doesn't throw when readonly
|
||||
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
|
||||
Pass input[type=file] showPicker() doesn't throw when readonly
|
||||
Pass input[type=hidden] showPicker() doesn't throw when readonly
|
||||
Pass input[type=image] showPicker() doesn't throw when readonly
|
||||
Pass input[type=month] showPicker() throws when readonly
|
||||
Pass input[type=number] showPicker() throws when readonly
|
||||
Pass input[type=password] showPicker() throws when readonly
|
||||
Pass input[type=radio] showPicker() doesn't throw when readonly
|
||||
Pass input[type=range] showPicker() doesn't throw when readonly
|
||||
Pass input[type=reset] showPicker() doesn't throw when readonly
|
||||
Pass input[type=search] showPicker() throws when readonly
|
||||
Pass input[type=submit] showPicker() doesn't throw when readonly
|
||||
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
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test showPicker() disabled/readonly requirement</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../resources/testdriver.js"></script>
|
||||
<script src="../../../../resources/testdriver-vendor.js"></script>
|
||||
<body></body>
|
||||
<script type=module>
|
||||
import inputTypes from "./input-types.js";
|
||||
|
||||
for (const inputType of inputTypes) {
|
||||
test(() => {
|
||||
const input = document.createElement("input");
|
||||
input.setAttribute("type", inputType);
|
||||
input.setAttribute("disabled", "");
|
||||
|
||||
assert_throws_dom('InvalidStateError', () => { input.showPicker(); });
|
||||
}, `input[type=${inputType}] showPicker() throws when disabled`);
|
||||
}
|
||||
|
||||
const noReadonlySupport = ['button', 'checkbox', 'color', 'file',
|
||||
'hidden', 'image', 'radio', 'range', 'reset', 'submit'];
|
||||
for (const inputType of inputTypes) {
|
||||
if (!noReadonlySupport.includes(inputType)) {
|
||||
promise_test(async () => {
|
||||
const input = document.createElement("input");
|
||||
input.setAttribute("type", inputType);
|
||||
input.setAttribute("readonly", "");
|
||||
|
||||
await test_driver.bless('show picker');
|
||||
assert_throws_dom('InvalidStateError', () => { input.showPicker(); });
|
||||
|
||||
assert_true(navigator.userActivation.isActive, 'User activation is not consumed for readonly showPicker() call');
|
||||
}, `input[type=${inputType}] showPicker() throws when readonly`);
|
||||
} else {
|
||||
promise_test(async () => {
|
||||
const input = document.createElement("input");
|
||||
input.setAttribute("type", inputType);
|
||||
input.setAttribute("readonly", "");
|
||||
document.body.appendChild(input);
|
||||
|
||||
await test_driver.bless('show picker');
|
||||
input.showPicker();
|
||||
input.blur();
|
||||
input.remove();
|
||||
|
||||
assert_false(navigator.userActivation.isActive, 'User activation is consumed for non-readonly showPicker() call');
|
||||
}, `input[type=${inputType}] showPicker() doesn't throw when readonly`);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Loading…
Reference in New Issue
Block a user