mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-21 00:38:56 +00:00
LibWeb: Implement autocorrect attribute
This commit is contained in:
parent
a6fb7c84e9
commit
829437c11d
Notes:
github-actions[bot]
2025-08-29 14:48:21 +00:00
Author: https://github.com/Calme1709
Commit: 829437c11d
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4907
Reviewed-by: https://github.com/Lubrsi ✅
Reviewed-by: https://github.com/ananas-dev
6 changed files with 428 additions and 1 deletions
|
@ -28,6 +28,7 @@ namespace AttributeNames {
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(async, "async") \
|
__ENUMERATE_HTML_ATTRIBUTE(async, "async") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(autocapitalize, "autocapitalize") \
|
__ENUMERATE_HTML_ATTRIBUTE(autocapitalize, "autocapitalize") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(autocomplete, "autocomplete") \
|
__ENUMERATE_HTML_ATTRIBUTE(autocomplete, "autocomplete") \
|
||||||
|
__ENUMERATE_HTML_ATTRIBUTE(autocorrect, "autocorrect") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(autofocus, "autofocus") \
|
__ENUMERATE_HTML_ATTRIBUTE(autofocus, "autofocus") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(autoplay, "autoplay") \
|
__ENUMERATE_HTML_ATTRIBUTE(autoplay, "autoplay") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(axis, "axis") \
|
__ENUMERATE_HTML_ATTRIBUTE(axis, "axis") \
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <LibWeb/HTML/HTMLBodyElement.h>
|
#include <LibWeb/HTML/HTMLBodyElement.h>
|
||||||
#include <LibWeb/HTML/HTMLDialogElement.h>
|
#include <LibWeb/HTML/HTMLDialogElement.h>
|
||||||
#include <LibWeb/HTML/HTMLElement.h>
|
#include <LibWeb/HTML/HTMLElement.h>
|
||||||
|
#include <LibWeb/HTML/HTMLInputElement.h>
|
||||||
#include <LibWeb/HTML/HTMLLabelElement.h>
|
#include <LibWeb/HTML/HTMLLabelElement.h>
|
||||||
#include <LibWeb/HTML/HTMLObjectElement.h>
|
#include <LibWeb/HTML/HTMLObjectElement.h>
|
||||||
#include <LibWeb/HTML/HTMLParagraphElement.h>
|
#include <LibWeb/HTML/HTMLParagraphElement.h>
|
||||||
|
@ -2325,4 +2326,64 @@ void HTMLElement::set_autocapitalize(String const& given_value)
|
||||||
MUST(set_attribute(HTML::AttributeNames::autocapitalize, given_value));
|
MUST(set_attribute(HTML::AttributeNames::autocapitalize, given_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/interaction.html#used-autocorrection-state
|
||||||
|
HTMLElement::AutocorrectionState HTMLElement::used_autocorrection_state() const
|
||||||
|
{
|
||||||
|
// The autocorrect attribute is an enumerated attribute with the following keywords and states:
|
||||||
|
// Keyword | State | Brief description
|
||||||
|
// on | on | The user agent is permitted to automatically correct spelling errors while the user
|
||||||
|
// (the empty string) | | types. Whether spelling is automatically corrected while typing left is for the user
|
||||||
|
// | | agent to decide, and may depend on the element as well as the user's preferences.
|
||||||
|
// off | off | The user agent is not allowed to automatically correct spelling while the user types.
|
||||||
|
|
||||||
|
// The attribute's invalid value default and missing value default are both the on state.
|
||||||
|
|
||||||
|
auto autocorrect_attribute_state = [](Optional<String> attribute) {
|
||||||
|
if (attribute.has_value() && attribute.value().equals_ignoring_ascii_case("off"sv))
|
||||||
|
return AutocorrectionState::Off;
|
||||||
|
|
||||||
|
return AutocorrectionState::On;
|
||||||
|
};
|
||||||
|
|
||||||
|
// To compute the used autocorrection state of an element element, run these steps:
|
||||||
|
// 1. If element is an input element whose type attribute is in one of the URL, E-mail, or Password states, then return off.
|
||||||
|
if (auto const* input_element = as_if<HTMLInputElement>(this)) {
|
||||||
|
if (first_is_one_of(input_element->type_state(), HTMLInputElement::TypeAttributeState::URL, HTMLInputElement::TypeAttributeState::Email, HTMLInputElement::TypeAttributeState::Password))
|
||||||
|
return AutocorrectionState::Off;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. If the autocorrect content attribute is present on element, then return the state of the attribute.
|
||||||
|
auto maybe_autocorrect_attribute = attribute(HTML::AttributeNames::autocorrect);
|
||||||
|
|
||||||
|
if (maybe_autocorrect_attribute.has_value())
|
||||||
|
return autocorrect_attribute_state(maybe_autocorrect_attribute);
|
||||||
|
|
||||||
|
// 3. If element is an autocapitalize-and-autocorrect inheriting element and has a non-null form owner, then return
|
||||||
|
// the state of element's form owner's autocorrect attribute.
|
||||||
|
if (auto const* form_associated_element = as_if<FormAssociatedElement>(this)) {
|
||||||
|
if (form_associated_element->is_autocapitalize_and_autocorrect_inheriting() && form_associated_element->form())
|
||||||
|
return autocorrect_attribute_state(form_associated_element->form()->attribute(HTML::AttributeNames::autocorrect));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Return on.
|
||||||
|
return AutocorrectionState::On;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/interaction.html#dom-autocorrect
|
||||||
|
bool HTMLElement::autocorrect() const
|
||||||
|
{
|
||||||
|
// The autocorrect getter steps are: return true if the element's used autocorrection state is on and false if the element's used autocorrection state is off.
|
||||||
|
return used_autocorrection_state() == AutocorrectionState::On;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/interaction.html#dom-autocorrect
|
||||||
|
void HTMLElement::set_autocorrect(bool given_value)
|
||||||
|
{
|
||||||
|
// The setter steps are: if the given value is true, then the element's autocorrect attribute must be set to "on"; otherwise it must be set to "off".
|
||||||
|
if (given_value)
|
||||||
|
MUST(set_attribute(HTML::AttributeNames::autocorrect, "on"_string));
|
||||||
|
else
|
||||||
|
MUST(set_attribute(HTML::AttributeNames::autocorrect, "off"_string));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,15 @@ public:
|
||||||
String autocapitalize() const;
|
String autocapitalize() const;
|
||||||
void set_autocapitalize(String const&);
|
void set_autocapitalize(String const&);
|
||||||
|
|
||||||
|
enum class AutocorrectionState {
|
||||||
|
On,
|
||||||
|
Off
|
||||||
|
};
|
||||||
|
|
||||||
|
AutocorrectionState used_autocorrection_state() const;
|
||||||
|
bool autocorrect() const;
|
||||||
|
void set_autocorrect(bool);
|
||||||
|
|
||||||
bool fire_a_synthetic_pointer_event(FlyString const& type, DOM::Element& target, bool not_trusted);
|
bool fire_a_synthetic_pointer_event(FlyString const& type, DOM::Element& target, bool not_trusted);
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/forms.html#category-label
|
// https://html.spec.whatwg.org/multipage/forms.html#category-label
|
||||||
|
|
|
@ -27,7 +27,7 @@ interface HTMLElement : Element {
|
||||||
[CEReactions] attribute boolean spellcheck;
|
[CEReactions] attribute boolean spellcheck;
|
||||||
[CEReactions] attribute DOMString writingSuggestions;
|
[CEReactions] attribute DOMString writingSuggestions;
|
||||||
[CEReactions] attribute DOMString autocapitalize;
|
[CEReactions] attribute DOMString autocapitalize;
|
||||||
[FIXME, CEReactions] attribute boolean autocorrect;
|
[CEReactions] attribute boolean autocorrect;
|
||||||
|
|
||||||
[LegacyNullToEmptyString, CEReactions] attribute Utf16DOMString innerText;
|
[LegacyNullToEmptyString, CEReactions] attribute Utf16DOMString innerText;
|
||||||
[LegacyNullToEmptyString, CEReactions] attribute Utf16DOMString outerText;
|
[LegacyNullToEmptyString, CEReactions] attribute Utf16DOMString outerText;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 9 tests
|
||||||
|
|
||||||
|
9 Pass
|
||||||
|
Pass Test that the autocorrect attribute is available on HTMLInputElement.
|
||||||
|
Pass Test that the autocorrect attribute is available on HTMLTextAreaElement.
|
||||||
|
Pass Test that the autocorrect attribute is available on div.
|
||||||
|
Pass Test that the autocorrect attribute is available on form.
|
||||||
|
Pass Test setting the autocorrect IDL attribute.
|
||||||
|
Pass Test setting the autocorrect attribute using setAttribute.
|
||||||
|
Pass Test inheriting autocorrection from a form.
|
||||||
|
Pass Test autocorrection in an editing host.
|
||||||
|
Pass Test autocorrection in password, URL, and email inputs.
|
|
@ -0,0 +1,342 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#autocorrection">
|
||||||
|
<body>
|
||||||
|
<script src="../../../../resources/testharness.js"></script>
|
||||||
|
<script src="../../../../resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_true('autocorrect' in document.createElement('input'));
|
||||||
|
}, "Test that the autocorrect attribute is available on HTMLInputElement.");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_true('autocorrect' in document.createElement('textarea'));
|
||||||
|
}, "Test that the autocorrect attribute is available on HTMLTextAreaElement.");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_true('autocorrect' in document.createElement('div'));
|
||||||
|
}, "Test that the autocorrect attribute is available on div.");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_true('autocorrect' in document.createElement('form'));
|
||||||
|
}, "Test that the autocorrect attribute is available on form.");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
[ document.createElement('input'),
|
||||||
|
document.createElement('textarea'),
|
||||||
|
document.createElement('div'),
|
||||||
|
document.createElement('form') ].forEach(e => {
|
||||||
|
e.autocorrect = true;
|
||||||
|
assert_true(e.autocorrect);
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), 'on');
|
||||||
|
|
||||||
|
e.autocorrect = 'hello';
|
||||||
|
assert_true(e.autocorrect);
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), 'on');
|
||||||
|
|
||||||
|
e.autocorrect = false;
|
||||||
|
assert_false(e.autocorrect);
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), 'off');
|
||||||
|
|
||||||
|
e.autocorrect = 0;
|
||||||
|
assert_false(e.autocorrect);
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), 'off');
|
||||||
|
});
|
||||||
|
}, "Test setting the autocorrect IDL attribute.");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
[ document.createElement('input'),
|
||||||
|
document.createElement('textarea'),
|
||||||
|
document.createElement('div'),
|
||||||
|
document.createElement('form') ].forEach(e => {
|
||||||
|
e.setAttribute('autocorrect', 'on');
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), 'on');
|
||||||
|
assert_true(e.autocorrect);
|
||||||
|
|
||||||
|
e.setAttribute('autocorrect', 'ON');
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), 'ON');
|
||||||
|
assert_true(e.autocorrect);
|
||||||
|
|
||||||
|
e.setAttribute('autocorrect', 'off');
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), 'off');
|
||||||
|
assert_false(e.autocorrect);
|
||||||
|
|
||||||
|
e.setAttribute('autocorrect', 'OFF');
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), 'OFF');
|
||||||
|
assert_false(e.autocorrect);
|
||||||
|
|
||||||
|
e.setAttribute('autocorrect', 'invalid_value');
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), 'invalid_value');
|
||||||
|
assert_true(e.autocorrect);
|
||||||
|
|
||||||
|
e.setAttribute('autocorrect', '');
|
||||||
|
assert_equals(e.getAttribute('autocorrect'), '');
|
||||||
|
assert_true(e.autocorrect);
|
||||||
|
|
||||||
|
e.removeAttribute('autocorrect');
|
||||||
|
assert_false(e.hasAttribute('autocorrect'));
|
||||||
|
assert_true(e.autocorrect);
|
||||||
|
});
|
||||||
|
}, "Test setting the autocorrect attribute using setAttribute.");
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
const testData = [
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: false,
|
||||||
|
uninheritedResult: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: false,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: false,
|
||||||
|
uninheritedResult: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: false,
|
||||||
|
uninheritedResult: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'bar',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'bar',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: false,
|
||||||
|
uninheritedResult: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'bar',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: false,
|
||||||
|
uninheritedResult: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: false,
|
||||||
|
uninheritedResult: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: false,
|
||||||
|
uninheritedResult: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'bar',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: true,
|
||||||
|
uninheritedResult: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const formElements = [
|
||||||
|
{element: 'button', inherits: true},
|
||||||
|
{element: 'fieldset', inherits: true},
|
||||||
|
{element: 'img', inherits: false},
|
||||||
|
{element: 'input', inherits: true},
|
||||||
|
{element: 'object', inherits: false},
|
||||||
|
{element: 'output', inherits: true},
|
||||||
|
{element: 'select', inherits: true},
|
||||||
|
{element: 'textarea', inherits: true},
|
||||||
|
];
|
||||||
|
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.id = 'form';
|
||||||
|
document.body.appendChild(form);
|
||||||
|
t.add_cleanup(() => form.remove());
|
||||||
|
|
||||||
|
testData.forEach(data => {
|
||||||
|
form.removeAttribute('autocorrect');
|
||||||
|
|
||||||
|
if (data.formValue !== null) {
|
||||||
|
form.setAttribute('autocorrect', data.formValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
formElements.forEach(elementData => {
|
||||||
|
const element = document.createElement(elementData.element);
|
||||||
|
form.appendChild(element);
|
||||||
|
|
||||||
|
const element2 = document.createElement(elementData.element);
|
||||||
|
element2.setAttribute('form', 'form');
|
||||||
|
document.body.appendChild(element2);
|
||||||
|
t.add_cleanup(() => element2.remove());
|
||||||
|
|
||||||
|
if (data.formElementValue !== null) {
|
||||||
|
element.setAttribute('autocorrect', data.formElementValue);
|
||||||
|
element2.setAttribute('autocorrect', data.formElementValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
const descriptionSuffix = 'with "' + data.formValue
|
||||||
|
+ '" and form element with "'+ data.formElementValue + '"';
|
||||||
|
|
||||||
|
if (elementData.inherits) {
|
||||||
|
assert_equals(element.autocorrect, data.inheritedResult,
|
||||||
|
`${elementData.element} element with form parent `
|
||||||
|
+ `${descriptionSuffix}`);
|
||||||
|
assert_equals(element2.autocorrect, data.inheritedResult,
|
||||||
|
`${elementData.element} element with form owner attribute`
|
||||||
|
+ ` set ${descriptionSuffix}`);
|
||||||
|
} else {
|
||||||
|
assert_equals(element.autocorrect, data.uninheritedResult,
|
||||||
|
`${elementData.element} element with form parent `
|
||||||
|
+ `${descriptionSuffix}`);
|
||||||
|
assert_equals(element2.autocorrect, data.uninheritedResult,
|
||||||
|
`${elementData.element} element with form owner attribute`
|
||||||
|
+ `set ${descriptionSuffix}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, "Test inheriting autocorrection from a form.")
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
const editingHost = document.createElement("div");
|
||||||
|
const container = document.createElement("br");
|
||||||
|
editingHost.contentEditable = true;
|
||||||
|
editingHost.appendChild(container);
|
||||||
|
document.body.appendChild(editingHost);
|
||||||
|
t.add_cleanup(() => editingHost.remove());
|
||||||
|
|
||||||
|
editingHost.autocorrect = false;
|
||||||
|
container.autocorrect = true;
|
||||||
|
|
||||||
|
assert_false(editingHost.autocorrect);
|
||||||
|
assert_true(container.autocorrect);
|
||||||
|
|
||||||
|
editingHost.autocorrect = true;
|
||||||
|
container.autocorrect = false;
|
||||||
|
|
||||||
|
assert_true(editingHost.autocorrect);
|
||||||
|
assert_false(container.autocorrect);
|
||||||
|
}, "Test autocorrection in an editing host.")
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
const form = document.createElement("form");
|
||||||
|
const passwordInput = document.createElement("input");
|
||||||
|
const emailInput = document.createElement("input");
|
||||||
|
const urlInput = document.createElement("input");
|
||||||
|
const textInput = document.createElement("input");
|
||||||
|
passwordInput.type = "password";
|
||||||
|
emailInput.type = "email";
|
||||||
|
urlInput.type = "url";
|
||||||
|
|
||||||
|
form.setAttribute("autocorrect", "on");
|
||||||
|
|
||||||
|
document.body.appendChild(form);
|
||||||
|
t.add_cleanup(() => form.remove());
|
||||||
|
for (const input of [passwordInput, emailInput, urlInput, textInput])
|
||||||
|
form.appendChild(input);
|
||||||
|
|
||||||
|
assert_false(passwordInput.autocorrect, `Input of type ${passwordInput.type}`);
|
||||||
|
assert_false(emailInput.autocorrect, `Input of type ${emailInput.type}`);
|
||||||
|
assert_false(urlInput.autocorrect, `Input of type ${urlInput.type}`);
|
||||||
|
assert_true(textInput.autocorrect, `Input of type ${textInput.type}`);
|
||||||
|
}, "Test autocorrection in password, URL, and email inputs.")
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue