mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-22 09:18:55 +00:00
LibWeb: Implement the spellcheck attribute
This commit is contained in:
parent
7be645a091
commit
87e0523664
Notes:
github-actions[bot]
2025-08-29 14:48:52 +00:00
Author: https://github.com/Calme1709
Commit: 87e0523664
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4907
Reviewed-by: https://github.com/Lubrsi ✅
Reviewed-by: https://github.com/ananas-dev
8 changed files with 143 additions and 1 deletions
|
@ -286,6 +286,7 @@ namespace AttributeNames {
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(sizes, "sizes") \
|
__ENUMERATE_HTML_ATTRIBUTE(sizes, "sizes") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(slot, "slot") \
|
__ENUMERATE_HTML_ATTRIBUTE(slot, "slot") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(span, "span") \
|
__ENUMERATE_HTML_ATTRIBUTE(span, "span") \
|
||||||
|
__ENUMERATE_HTML_ATTRIBUTE(spellcheck, "spellcheck") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(src, "src") \
|
__ENUMERATE_HTML_ATTRIBUTE(src, "src") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(srcdoc, "srcdoc") \
|
__ENUMERATE_HTML_ATTRIBUTE(srcdoc, "srcdoc") \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(srclang, "srclang") \
|
__ENUMERATE_HTML_ATTRIBUTE(srclang, "srclang") \
|
||||||
|
|
|
@ -2133,4 +2133,66 @@ bool HTMLElement::draggable() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/interaction.html#dom-spellcheck
|
||||||
|
bool HTMLElement::spellcheck() const
|
||||||
|
{
|
||||||
|
// The spellcheck attribute is an enumerated attribute with the following keywords and states:
|
||||||
|
// Keyword | State | Brief description
|
||||||
|
// true | True | Spelling and grammar will be checked.
|
||||||
|
// (the empty string) | |
|
||||||
|
// false | False | and grammar will not be checked.
|
||||||
|
|
||||||
|
// The attribute's missing value default and invalid value default are both the Default state. The default state
|
||||||
|
// indicates that the element is to act according to a default behavior, possibly based on the parent element's
|
||||||
|
// own spellcheck state, as defined below.
|
||||||
|
|
||||||
|
// For each element, user agents must establish a default behavior, either through defaults or through preferences
|
||||||
|
// expressed by the user. There are three possible default behaviors for each element:
|
||||||
|
|
||||||
|
// true-by-default
|
||||||
|
// The element will be checked for spelling and grammar if its contents are editable and spellchecking is not
|
||||||
|
// explicitly disabled through the spellcheck attribute.
|
||||||
|
// false-by-default
|
||||||
|
// The element will never be checked for spelling and grammar unless spellchecking is explicitly enabled
|
||||||
|
// through the spellcheck attribute.
|
||||||
|
// inherit-by-default
|
||||||
|
// The element's default behavior is the same as its parent element's. Elements that have no parent element
|
||||||
|
// cannot have this as their default behavior.
|
||||||
|
|
||||||
|
// NOTE: We use "true-by-default" for elements which are editable, editing hosts, or form associated text control
|
||||||
|
// elements "false-by-default" for root elements, and "inherit-by-default" for other elements.
|
||||||
|
|
||||||
|
auto maybe_spellcheck_attribute = attribute(HTML::AttributeNames::spellcheck);
|
||||||
|
|
||||||
|
// The spellcheck IDL attribute, on getting, must return true if the element's spellcheck content attribute is in the True state,
|
||||||
|
if (maybe_spellcheck_attribute.has_value() && (maybe_spellcheck_attribute.value().equals_ignoring_ascii_case("true"sv) || maybe_spellcheck_attribute.value().is_empty()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!maybe_spellcheck_attribute.has_value() || !maybe_spellcheck_attribute.value().equals_ignoring_ascii_case("false"sv)) {
|
||||||
|
// or if the element's spellcheck content attribute is in the Default state and the element's default behavior is true-by-default,
|
||||||
|
if (is_editable_or_editing_host() || is<FormAssociatedTextControlElement>(this))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// or if the element's spellcheck content attribute is in the Default state and the element's default behavior is inherit-by-default
|
||||||
|
if (auto* parent_html_element = first_ancestor_of_type<HTMLElement>()) {
|
||||||
|
// and the element's parent element's spellcheck IDL attribute would return true;
|
||||||
|
if (parent_html_element->spellcheck())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if none of those conditions applies, then the attribute must instead return false.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/interaction.html#dom-spellcheck
|
||||||
|
void HTMLElement::set_spellcheck(bool spellcheck)
|
||||||
|
{
|
||||||
|
// On setting, if the new value is true, then the element's spellcheck content attribute must be set to "true", otherwise it must be set to "false".
|
||||||
|
if (spellcheck)
|
||||||
|
MUST(set_attribute(HTML::AttributeNames::spellcheck, "true"_string));
|
||||||
|
else
|
||||||
|
MUST(set_attribute(HTML::AttributeNames::spellcheck, "false"_string));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,9 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] String access_key_label() const;
|
[[nodiscard]] String access_key_label() const;
|
||||||
|
|
||||||
|
bool spellcheck() const;
|
||||||
|
void set_spellcheck(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
|
||||||
|
|
|
@ -24,7 +24,7 @@ interface HTMLElement : Element {
|
||||||
[Reflect=accesskey, CEReactions] attribute DOMString accessKey;
|
[Reflect=accesskey, CEReactions] attribute DOMString accessKey;
|
||||||
readonly attribute DOMString accessKeyLabel;
|
readonly attribute DOMString accessKeyLabel;
|
||||||
[CEReactions] attribute boolean draggable;
|
[CEReactions] attribute boolean draggable;
|
||||||
[FIXME, CEReactions] attribute boolean spellcheck;
|
[CEReactions] attribute boolean spellcheck;
|
||||||
[FIXME, CEReactions] attribute DOMString autocapitalize;
|
[FIXME, CEReactions] attribute DOMString autocapitalize;
|
||||||
[FIXME, CEReactions] attribute boolean autocorrect;
|
[FIXME, CEReactions] attribute boolean autocorrect;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 1 tests
|
||||||
|
|
||||||
|
1 Pass
|
||||||
|
Pass keyword false
|
|
@ -0,0 +1,8 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 3 tests
|
||||||
|
|
||||||
|
3 Pass
|
||||||
|
Pass Getting spellcheck IDL attribute
|
||||||
|
Pass Setting spellcheck IDL attribute to true
|
||||||
|
Pass Setting spellcheck IDL attribute to false
|
|
@ -0,0 +1,27 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="help" href="https://html.spec.whatwg.org/#attr-spellcheck">
|
||||||
|
<link rel="help" href="https://html.spec.whatwg.org/#enumerated-attribute">
|
||||||
|
<meta name="assert" content="@spellcheck values are ASCII case-insensitive">
|
||||||
|
<script src="../../../../resources/testharness.js"></script>
|
||||||
|
<script src="../../../../resources/testharnessreport.js"></script>
|
||||||
|
<!--
|
||||||
|
While <div> and <span> aren’t defined as “checkable for the purposes of this
|
||||||
|
feature”, this has no effect on the attribute’s state.
|
||||||
|
|
||||||
|
We wrap the <span> elements under test with <div> elements so the checking
|
||||||
|
enabled algorithm stops at step 4 (ancestor content attribute), before steps
|
||||||
|
relying on user-agent-defined behavior (see [#concept-spellcheck-default]).
|
||||||
|
-->
|
||||||
|
<div spellcheck="true"><span spellcheck="false"></span></div>
|
||||||
|
<div spellcheck="true"><span spellcheck="FaLsE"></span></div>
|
||||||
|
<div spellcheck="true"><span spellcheck="falſe"></span></div>
|
||||||
|
<script>
|
||||||
|
const span = document.querySelectorAll("span");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_equals(span[0].spellcheck, false, "lowercase valid");
|
||||||
|
assert_equals(span[1].spellcheck, false, "mixed case valid");
|
||||||
|
assert_equals(span[2].spellcheck, true, "non-ASCII invalid");
|
||||||
|
}, "keyword false");
|
||||||
|
</script>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Editing: spellcheck attribute test</title>
|
||||||
|
<link rel="author" title="Baidu" href="mailto: guopengcheng@baidu.com"/>
|
||||||
|
<link rel="help" href="https://html.spec.whatwg.org/multipage/#spelling-and-grammar-checking"/>
|
||||||
|
<script src="../../../../resources/testharness.js"></script>
|
||||||
|
<script src="../../../../resources/testharnessreport.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="log"></div>
|
||||||
|
<textarea id="testText1" spellcheck="true">Test textarea with spellcheck is true</textarea>
|
||||||
|
<textarea id="testText2" spellcheck="false">Test textarea with spellcheck is false</textarea>
|
||||||
|
<script type="text/javascript">
|
||||||
|
test(function() {
|
||||||
|
assert_true(document.getElementById("testText1").spellcheck, "check for testText1 spellcheck value");
|
||||||
|
assert_false(document.getElementById("testText2").spellcheck, "check for testText2 spellcheck value");
|
||||||
|
}, "Getting spellcheck IDL attribute");
|
||||||
|
test(function() {
|
||||||
|
var testElement = document.createElement("testElement");
|
||||||
|
testElement.contentEditable = true;
|
||||||
|
testElement.spellcheck = true;
|
||||||
|
assert_true(testElement.spellcheck, "check for testElement.spellcheck value");
|
||||||
|
assert_equals(testElement.getAttribute("spellcheck"), "true");
|
||||||
|
}, "Setting spellcheck IDL attribute to true");
|
||||||
|
test(function() {
|
||||||
|
var testElement = document.createElement("testElement");
|
||||||
|
testElement.contentEditable = true;
|
||||||
|
testElement.spellcheck = false;
|
||||||
|
assert_false(testElement.spellcheck, "check for testText2 spellcheck value");
|
||||||
|
assert_equals(testElement.getAttribute("spellcheck"), "false");
|
||||||
|
}, "Setting spellcheck IDL attribute to false");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue