diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index 7693dccee12..c807b081176 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -2901,4 +2902,43 @@ void Element::inherit_counters() m_counters_set = move(element_counters); } +// https://html.spec.whatwg.org/multipage/dom.html#the-lang-and-xml:lang-attributes +Optional Element::lang() const +{ + // 1. If the node is an element that has a lang attribute in the XML namespace set + // Use the value of that attribute. + auto maybe_xml_lang = get_attribute_ns(Namespace::XML, HTML::AttributeNames::lang); + if (maybe_xml_lang.has_value()) + return maybe_xml_lang.release_value(); + + // 2. If the node is an HTML element or an element in the SVG namespace, and it has a lang in no namespace attribute set + // Use the value of that attribute. + if (is_html_element() || namespace_uri() == Namespace::SVG) { + auto maybe_lang = get_attribute(HTML::AttributeNames::lang); + if (maybe_lang.has_value()) + return maybe_lang.release_value(); + } + + // 3. If the node's parent is a shadow root + // Use the language of that shadow root's host. + if (auto const* parent = parent_element()) { + if (parent->is_shadow_root()) + return parent->shadow_root()->host()->lang(); + } + + // 4. If the node's parent element is not null + // Use the language of that parent element. + if (auto const* parent = parent_element()) + return parent->lang(); + + // 5. Otherwise + // - If there is a pragma-set default language set, then that is the language of the node. + // - If there is no pragma-set default language set, then language information from a higher-level protocol (such as HTTP), + // if any, must be used as the final fallback language instead. + // - In the absence of any such language information, and in cases where the higher-level protocol reports multiple languages, + // the language of the node is unknown, and the corresponding language tag is the empty string. + // Default locale sounds like a reasonable fallback here. + return {}; +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index a54d38b8708..14720cd6f75 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -123,6 +123,8 @@ public: Optional get_attribute_ns(Optional const& namespace_, FlyString const& name) const; String get_attribute_value(FlyString const& local_name, Optional const& namespace_ = {}) const; + Optional lang() const; + WebIDL::ExceptionOr set_attribute(FlyString const& name, String const& value); WebIDL::ExceptionOr set_attribute_ns(Optional const& namespace_, FlyString const& qualified_name, String const& value);