From 87e0523664a5421a95c02c872961d7c456314b0e Mon Sep 17 00:00:00 2001 From: Callum Law Date: Mon, 26 May 2025 12:02:22 +1200 Subject: [PATCH] LibWeb: Implement the spellcheck attribute --- Libraries/LibWeb/HTML/AttributeNames.h | 1 + Libraries/LibWeb/HTML/HTMLElement.cpp | 62 +++++++++++++++++++ Libraries/LibWeb/HTML/HTMLElement.h | 3 + Libraries/LibWeb/HTML/HTMLElement.idl | 2 +- ...heck-enumerated-ascii-case-insensitive.txt | 6 ++ .../user-interaction-editing-spellcheck.txt | 8 +++ ...eck-enumerated-ascii-case-insensitive.html | 27 ++++++++ .../user-interaction-editing-spellcheck.html | 35 +++++++++++ 8 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/spellcheck-enumerated-ascii-case-insensitive.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/user-interaction-editing-spellcheck.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/spellcheck-enumerated-ascii-case-insensitive.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/user-interaction-editing-spellcheck.html diff --git a/Libraries/LibWeb/HTML/AttributeNames.h b/Libraries/LibWeb/HTML/AttributeNames.h index 446c9ade1e7..1afe13b69ee 100644 --- a/Libraries/LibWeb/HTML/AttributeNames.h +++ b/Libraries/LibWeb/HTML/AttributeNames.h @@ -286,6 +286,7 @@ namespace AttributeNames { __ENUMERATE_HTML_ATTRIBUTE(sizes, "sizes") \ __ENUMERATE_HTML_ATTRIBUTE(slot, "slot") \ __ENUMERATE_HTML_ATTRIBUTE(span, "span") \ + __ENUMERATE_HTML_ATTRIBUTE(spellcheck, "spellcheck") \ __ENUMERATE_HTML_ATTRIBUTE(src, "src") \ __ENUMERATE_HTML_ATTRIBUTE(srcdoc, "srcdoc") \ __ENUMERATE_HTML_ATTRIBUTE(srclang, "srclang") \ diff --git a/Libraries/LibWeb/HTML/HTMLElement.cpp b/Libraries/LibWeb/HTML/HTMLElement.cpp index c91afadc486..ac5d902f069 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -2133,4 +2133,66 @@ bool HTMLElement::draggable() const 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(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()) { + // 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)); +} + } diff --git a/Libraries/LibWeb/HTML/HTMLElement.h b/Libraries/LibWeb/HTML/HTMLElement.h index 33f97f32db8..492785128fa 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.h +++ b/Libraries/LibWeb/HTML/HTMLElement.h @@ -117,6 +117,9 @@ public: [[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); // https://html.spec.whatwg.org/multipage/forms.html#category-label diff --git a/Libraries/LibWeb/HTML/HTMLElement.idl b/Libraries/LibWeb/HTML/HTMLElement.idl index 60e8e4fc6b7..743a0f89d60 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.idl +++ b/Libraries/LibWeb/HTML/HTMLElement.idl @@ -24,7 +24,7 @@ interface HTMLElement : Element { [Reflect=accesskey, CEReactions] attribute DOMString accessKey; readonly attribute DOMString accessKeyLabel; [CEReactions] attribute boolean draggable; - [FIXME, CEReactions] attribute boolean spellcheck; + [CEReactions] attribute boolean spellcheck; [FIXME, CEReactions] attribute DOMString autocapitalize; [FIXME, CEReactions] attribute boolean autocorrect; diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/spellcheck-enumerated-ascii-case-insensitive.txt b/Tests/LibWeb/Text/expected/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/spellcheck-enumerated-ascii-case-insensitive.txt new file mode 100644 index 00000000000..4cdd7244625 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/spellcheck-enumerated-ascii-case-insensitive.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass keyword false \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/user-interaction-editing-spellcheck.txt b/Tests/LibWeb/Text/expected/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/user-interaction-editing-spellcheck.txt new file mode 100644 index 00000000000..c88bf225af1 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/user-interaction-editing-spellcheck.txt @@ -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 \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/spellcheck-enumerated-ascii-case-insensitive.html b/Tests/LibWeb/Text/input/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/spellcheck-enumerated-ascii-case-insensitive.html new file mode 100644 index 00000000000..c88c80b29e1 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/spellcheck-enumerated-ascii-case-insensitive.html @@ -0,0 +1,27 @@ + + + + + + + + +
+
+
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/user-interaction-editing-spellcheck.html b/Tests/LibWeb/Text/input/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/user-interaction-editing-spellcheck.html new file mode 100644 index 00000000000..5af4e2f6201 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/editing/editing-0/spelling-and-grammar-checking/user-interaction-editing-spellcheck.html @@ -0,0 +1,35 @@ + + + + Editing: spellcheck attribute test + + + + + + +
+ + + + +