mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-21 08:48:57 +00:00
LibWeb: Implement the autocapitalize attribute
This commit is contained in:
parent
11457e533a
commit
a6fb7c84e9
Notes:
github-actions[bot]
2025-08-29 14:48:31 +00:00
Author: https://github.com/Calme1709
Commit: a6fb7c84e9
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 808 additions and 1 deletions
|
@ -26,6 +26,7 @@ namespace AttributeNames {
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(archive, "archive") \
|
__ENUMERATE_HTML_ATTRIBUTE(archive, "archive") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(as, "as") \
|
__ENUMERATE_HTML_ATTRIBUTE(as, "as") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(async, "async") \
|
__ENUMERATE_HTML_ATTRIBUTE(async, "async") \
|
||||||
|
__ENUMERATE_HTML_ATTRIBUTE(autocapitalize, "autocapitalize") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(autocomplete, "autocomplete") \
|
__ENUMERATE_HTML_ATTRIBUTE(autocomplete, "autocomplete") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(autofocus, "autofocus") \
|
__ENUMERATE_HTML_ATTRIBUTE(autofocus, "autofocus") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(autoplay, "autoplay") \
|
__ENUMERATE_HTML_ATTRIBUTE(autoplay, "autoplay") \
|
||||||
|
|
|
@ -2232,4 +2232,97 @@ void HTMLElement::set_writing_suggestions(String const& given_value)
|
||||||
MUST(set_attribute(HTML::AttributeNames::writingsuggestions, given_value));
|
MUST(set_attribute(HTML::AttributeNames::writingsuggestions, given_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/interaction.html#own-autocapitalization-hint
|
||||||
|
HTMLElement::AutocapitalizationHint HTMLElement::own_autocapitalization_hint() const
|
||||||
|
{
|
||||||
|
// The autocapitalization processing model is based on selecting among five autocapitalization hints, defined as follows:
|
||||||
|
//
|
||||||
|
// default
|
||||||
|
// The user agent and input method should make their own determination of whether or not to enable autocapitalization.
|
||||||
|
// none
|
||||||
|
// No autocapitalization should be applied (all letters should default to lowercase).
|
||||||
|
// sentences
|
||||||
|
// The first letter of each sentence should default to a capital letter; all other letters should default to lowercase.
|
||||||
|
// words
|
||||||
|
// The first letter of each word should default to a capital letter; all other letters should default to lowercase.
|
||||||
|
// characters
|
||||||
|
// All letters should default to uppercase.
|
||||||
|
|
||||||
|
// The autocapitalize attribute is an enumerated attribute whose states are the possible autocapitalization hints.
|
||||||
|
// The autocapitalization hint specified by the attribute's state combines with other considerations to form the
|
||||||
|
// used autocapitalization hint, which informs the behavior of the user agent. The keywords for this attribute and
|
||||||
|
// their state mappings are as follows:
|
||||||
|
|
||||||
|
// Keyword | State
|
||||||
|
// off | none
|
||||||
|
// none |
|
||||||
|
// on | sentences
|
||||||
|
// sentences |
|
||||||
|
// words | words
|
||||||
|
// characters | characters
|
||||||
|
|
||||||
|
// The attribute's missing value default is the default state, and its invalid value default is the sentences state.
|
||||||
|
|
||||||
|
// To compute the own autocapitalization hint of an element element, run the following steps:
|
||||||
|
// 1. If the autocapitalize content attribute is present on element, and its value is not the empty string, return the
|
||||||
|
// state of the attribute.
|
||||||
|
auto maybe_autocapitalize_attribute = attribute(HTML::AttributeNames::autocapitalize);
|
||||||
|
|
||||||
|
if (maybe_autocapitalize_attribute.has_value() && !maybe_autocapitalize_attribute.value().is_empty()) {
|
||||||
|
auto autocapitalize_attribute_string_view = maybe_autocapitalize_attribute.value().bytes_as_string_view();
|
||||||
|
|
||||||
|
if (autocapitalize_attribute_string_view.is_one_of_ignoring_ascii_case("off"sv, "none"sv))
|
||||||
|
return AutocapitalizationHint::None;
|
||||||
|
|
||||||
|
if (autocapitalize_attribute_string_view.equals_ignoring_ascii_case("words"sv))
|
||||||
|
return AutocapitalizationHint::Words;
|
||||||
|
|
||||||
|
if (autocapitalize_attribute_string_view.equals_ignoring_ascii_case("characters"sv))
|
||||||
|
return AutocapitalizationHint::Characters;
|
||||||
|
|
||||||
|
return AutocapitalizationHint::Sentences;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If element is an autocapitalize-and-autocorrect inheriting element and has a non-null form owner, return the own autocapitalization hint of element's form owner.
|
||||||
|
auto const* form_associated_element = as_if<FormAssociatedElement>(this);
|
||||||
|
if (form_associated_element && form_associated_element->is_autocapitalize_and_autocorrect_inheriting() && form_associated_element->form())
|
||||||
|
return form_associated_element->form()->own_autocapitalization_hint();
|
||||||
|
|
||||||
|
// 3. Return default.
|
||||||
|
return AutocapitalizationHint::Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/interaction.html#attr-autocapitalize
|
||||||
|
String HTMLElement::autocapitalize() const
|
||||||
|
{
|
||||||
|
// The autocapitalize getter steps are to:
|
||||||
|
// 1. Let state be the own autocapitalization hint of this.
|
||||||
|
auto state = own_autocapitalization_hint();
|
||||||
|
|
||||||
|
// 2. If state is default, then return the empty string.
|
||||||
|
// 3. If state is none, then return "none".
|
||||||
|
// 4. If state is sentences, then return "sentences".
|
||||||
|
// 5. Return the keyword value corresponding to state.
|
||||||
|
switch (state) {
|
||||||
|
case AutocapitalizationHint::Default:
|
||||||
|
return String {};
|
||||||
|
case AutocapitalizationHint::None:
|
||||||
|
return "none"_string;
|
||||||
|
case AutocapitalizationHint::Sentences:
|
||||||
|
return "sentences"_string;
|
||||||
|
case AutocapitalizationHint::Words:
|
||||||
|
return "words"_string;
|
||||||
|
case AutocapitalizationHint::Characters:
|
||||||
|
return "characters"_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HTMLElement::set_autocapitalize(String const& given_value)
|
||||||
|
{
|
||||||
|
// The autocapitalize setter steps are to set the autocapitalize content attribute to the given value.
|
||||||
|
MUST(set_attribute(HTML::AttributeNames::autocapitalize, given_value));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,18 @@ public:
|
||||||
String writing_suggestions() const;
|
String writing_suggestions() const;
|
||||||
void set_writing_suggestions(String const&);
|
void set_writing_suggestions(String const&);
|
||||||
|
|
||||||
|
enum class AutocapitalizationHint {
|
||||||
|
Default,
|
||||||
|
None,
|
||||||
|
Sentences,
|
||||||
|
Words,
|
||||||
|
Characters
|
||||||
|
};
|
||||||
|
|
||||||
|
AutocapitalizationHint own_autocapitalization_hint() const;
|
||||||
|
String autocapitalize() const;
|
||||||
|
void set_autocapitalize(String const&);
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -26,7 +26,7 @@ interface HTMLElement : Element {
|
||||||
[CEReactions] attribute boolean draggable;
|
[CEReactions] attribute boolean draggable;
|
||||||
[CEReactions] attribute boolean spellcheck;
|
[CEReactions] attribute boolean spellcheck;
|
||||||
[CEReactions] attribute DOMString writingSuggestions;
|
[CEReactions] attribute DOMString writingSuggestions;
|
||||||
[FIXME, CEReactions] attribute DOMString autocapitalize;
|
[CEReactions] attribute DOMString autocapitalize;
|
||||||
[FIXME, CEReactions] attribute boolean autocorrect;
|
[FIXME, CEReactions] attribute boolean autocorrect;
|
||||||
|
|
||||||
[LegacyNullToEmptyString, CEReactions] attribute Utf16DOMString innerText;
|
[LegacyNullToEmptyString, CEReactions] attribute Utf16DOMString innerText;
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 8 tests
|
||||||
|
|
||||||
|
8 Pass
|
||||||
|
Pass Test that the autocapitalize is available on HTMLInputElement.
|
||||||
|
Pass Test that the autocapitalize is available on HTMLTextAreaElement.
|
||||||
|
Pass Test that the autocapitalize is available on div.
|
||||||
|
Pass Test deprecated values of autocapitalize.
|
||||||
|
Pass Test reflection of autocapitalize.
|
||||||
|
Pass Test that the IDL attribute returns the empty string if the content attribute is not set.
|
||||||
|
Pass Test inheriting values from a form.
|
||||||
|
Pass Verify that even input types that are never autocapitalized support the IDL interface.
|
|
@ -0,0 +1,688 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#autocapitalization">
|
||||||
|
<body>
|
||||||
|
<script src="../../../../resources/testharness.js"></script>
|
||||||
|
<script src="../../../../resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_true('autocapitalize' in document.createElement('input'));
|
||||||
|
}, "Test that the autocapitalize is available on HTMLInputElement.")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_true('autocapitalize' in document.createElement('textarea'));
|
||||||
|
}, "Test that the autocapitalize is available on HTMLTextAreaElement.")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_true('autocapitalize' in document.createElement('div'));
|
||||||
|
}, "Test that the autocapitalize is available on div.")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var elements = [ document.createElement('input'),
|
||||||
|
document.createElement('textarea'),
|
||||||
|
document.createElement('div') ];
|
||||||
|
|
||||||
|
elements.forEach(function(e) {
|
||||||
|
e.autocapitalize = 'on';
|
||||||
|
assert_equals(e.autocapitalize, 'sentences');
|
||||||
|
|
||||||
|
e.autocapitalize = 'off';
|
||||||
|
assert_equals(e.autocapitalize, 'none');
|
||||||
|
});
|
||||||
|
}, "Test deprecated values of autocapitalize.");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var elements = [ document.createElement('input'),
|
||||||
|
document.createElement('textarea'),
|
||||||
|
document.createElement('div') ];
|
||||||
|
var knownValues = [ 'none', 'characters', 'words', 'sentences' ];
|
||||||
|
|
||||||
|
elements.forEach(function(e) {
|
||||||
|
// Default value.
|
||||||
|
assert_equals(e.autocapitalize, '');
|
||||||
|
|
||||||
|
// Empty value.
|
||||||
|
e.autocapitalize = '';
|
||||||
|
assert_equals(e.autocapitalize, '');
|
||||||
|
assert_equals(e.getAttribute('autocapitalize'), '');
|
||||||
|
e.setAttribute('autocapitalize', '');
|
||||||
|
assert_equals(e.autocapitalize, '');
|
||||||
|
assert_equals(e.getAttribute('autocapitalize'), '');
|
||||||
|
assert_equals(e.autocapitalize, '');
|
||||||
|
|
||||||
|
// Invalid value.
|
||||||
|
e.autocapitalize = 'foo';
|
||||||
|
assert_equals(e.autocapitalize, 'sentences');
|
||||||
|
assert_equals(e.getAttribute('autocapitalize'), 'foo');
|
||||||
|
e.setAttribute('autocapitalize', 'bar');
|
||||||
|
assert_equals(e.autocapitalize, 'sentences');
|
||||||
|
assert_equals(e.getAttribute('autocapitalize'), 'bar');
|
||||||
|
|
||||||
|
// Default value.
|
||||||
|
e.removeAttribute('autocapitalize');
|
||||||
|
assert_equals(e.autocapitalize, '');
|
||||||
|
assert_equals(e.getAttribute('autocapitalize'), null);
|
||||||
|
|
||||||
|
// Case insensitive.
|
||||||
|
e.setAttribute('autocapitalize', 'NoNe');
|
||||||
|
assert_equals(e.autocapitalize, 'none');
|
||||||
|
assert_equals(e.getAttribute('autocapitalize'), 'NoNe');
|
||||||
|
e.autocapitalize = 'WORDS';
|
||||||
|
assert_equals(e.autocapitalize, 'words');
|
||||||
|
assert_equals(e.getAttribute('autocapitalize'), 'WORDS');
|
||||||
|
|
||||||
|
knownValues.forEach(function(value) {
|
||||||
|
e.setAttribute('autocapitalize', value);
|
||||||
|
assert_equals(e.autocapitalize, value);
|
||||||
|
assert_equals(e.getAttribute('autocapitalize'), value);
|
||||||
|
|
||||||
|
e.removeAttribute('autocapitalize');
|
||||||
|
|
||||||
|
e.autocapitalize = value;
|
||||||
|
assert_equals(e.autocapitalize, value);
|
||||||
|
assert_equals(e.getAttribute('autocapitalize'), value);
|
||||||
|
|
||||||
|
e.removeAttribute('autocapitalize');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, "Test reflection of autocapitalize.");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var testData = [ 'text',
|
||||||
|
'search',
|
||||||
|
'email',
|
||||||
|
'url',
|
||||||
|
'tel',
|
||||||
|
'number',
|
||||||
|
'date',
|
||||||
|
'color',
|
||||||
|
'password' ];
|
||||||
|
|
||||||
|
testData.forEach(function(data) {
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.type = data;
|
||||||
|
assert_equals(input.autocapitalize, '');
|
||||||
|
|
||||||
|
// Verify that wrapping the input element in a form doesn't change the
|
||||||
|
// defaults.
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.appendChild(input);
|
||||||
|
assert_equals(input.autocapitalize, '');
|
||||||
|
});
|
||||||
|
}, "Test that the IDL attribute returns the empty string if the content "
|
||||||
|
+ "attribute is not set.")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const testData = [
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: '',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: '',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: 'none',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: 'characters',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: 'characters',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: 'words',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: 'words',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: 'sentences',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: null,
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: '',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: '',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'none',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'characters',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: 'characters',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'words',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: 'words',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'sentences',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: '',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'none',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'characters',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: 'characters',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'words',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: 'words',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'sentences',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'on',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'none',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'characters',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: 'characters',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'words',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: 'words',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'sentences',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'off',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'none',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'none',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'none',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'none',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'none',
|
||||||
|
formElementValue: 'none',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'none',
|
||||||
|
formElementValue: 'characters',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: 'characters',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'none',
|
||||||
|
formElementValue: 'words',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: 'words',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'none',
|
||||||
|
formElementValue: 'sentences',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'none',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'characters',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'characters',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'characters',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'characters',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'characters',
|
||||||
|
formElementValue: 'none',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'characters',
|
||||||
|
formElementValue: 'characters',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: 'characters',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'characters',
|
||||||
|
formElementValue: 'words',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: 'words',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'characters',
|
||||||
|
formElementValue: 'sentences',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'characters',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'words',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'words',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'words',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'words',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'words',
|
||||||
|
formElementValue: 'none',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'words',
|
||||||
|
formElementValue: 'characters',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: 'characters',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'words',
|
||||||
|
formElementValue: 'words',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: 'words',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'words',
|
||||||
|
formElementValue: 'sentences',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'words',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'sentences',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'sentences',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'sentences',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'sentences',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'sentences',
|
||||||
|
formElementValue: 'none',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'sentences',
|
||||||
|
formElementValue: 'characters',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: 'characters',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'sentences',
|
||||||
|
formElementValue: 'words',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: 'words',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'sentences',
|
||||||
|
formElementValue: 'sentences',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'sentences',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: null,
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: '',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: 'on',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: 'off',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: 'none',
|
||||||
|
inheritedResult: 'none',
|
||||||
|
uninheritedResult: 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: 'characters',
|
||||||
|
inheritedResult: 'characters',
|
||||||
|
uninheritedResult: 'characters',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: 'words',
|
||||||
|
inheritedResult: 'words',
|
||||||
|
uninheritedResult: 'words',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: 'sentences',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formValue: 'foo',
|
||||||
|
formElementValue: 'foo',
|
||||||
|
inheritedResult: 'sentences',
|
||||||
|
uninheritedResult: 'sentences',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
testData.forEach(data => {
|
||||||
|
form.removeAttribute('autocapitalize');
|
||||||
|
|
||||||
|
if (data.formValue !== null) {
|
||||||
|
form.setAttribute('autocapitalize', 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);
|
||||||
|
|
||||||
|
if (data.formElementValue !== null) {
|
||||||
|
element.setAttribute('autocapitalize', data.formElementValue);
|
||||||
|
element2.setAttribute('autocapitalize', data.formElementValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
const descriptionSuffix = 'with "' + data.formValue
|
||||||
|
+ '" and form element with "'+ data.formElementValue + '"';
|
||||||
|
|
||||||
|
if (elementData.inherits) {
|
||||||
|
assert_equals(element.autocapitalize, data.inheritedResult,
|
||||||
|
`${elementData.element} element with form parent `
|
||||||
|
+ `${descriptionSuffix}`);
|
||||||
|
assert_equals(element2.autocapitalize, data.inheritedResult,
|
||||||
|
`${elementData.element} element with form owner attribute`
|
||||||
|
+ ` set ${descriptionSuffix}`);
|
||||||
|
} else {
|
||||||
|
assert_equals(element.autocapitalize, data.uninheritedResult,
|
||||||
|
`${elementData.element} element with form parent `
|
||||||
|
+ `${descriptionSuffix}`);
|
||||||
|
assert_equals(element2.autocapitalize, data.uninheritedResult,
|
||||||
|
`${elementData.element} element with form owner attribute`
|
||||||
|
+ `set ${descriptionSuffix}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, "Test inheriting values from a form.")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
const testData = [ 'text',
|
||||||
|
'search',
|
||||||
|
'email',
|
||||||
|
'url',
|
||||||
|
'tel',
|
||||||
|
'number',
|
||||||
|
'date',
|
||||||
|
'color',
|
||||||
|
'password' ];
|
||||||
|
|
||||||
|
testData.forEach(function(data) {
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.setAttribute('autocapitalize', 'sentences');
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.setAttribute('type', data);
|
||||||
|
form.appendChild(input);
|
||||||
|
|
||||||
|
assert_equals(input.autocapitalize, 'sentences');
|
||||||
|
});
|
||||||
|
}, "Verify that even input types that are never autocapitalized support the "
|
||||||
|
+ "IDL interface.")
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue