diff options
author | stelar7 <dudedbz@gmail.com> | 2023-06-02 21:08:14 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-06-03 05:56:00 +0200 |
commit | 8773122f6b55044a738dcc22e4342d3de4c4c25d (patch) | |
tree | 6d2d19d58f06dc2817131a1e3d3422c139696300 | |
parent | 870bcd56df13a0a6123c0d15228105e31b7292a6 (diff) | |
download | serenity-8773122f6b55044a738dcc22e4342d3de4c4c25d.zip |
LibWeb: Implement the <summary> element
-rw-r--r-- | Userland/Libraries/LibWeb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/ElementFactory.cpp | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Forward.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.cpp | 67 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.h | 31 |
5 files changed, 104 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 61f8ebfcbf..4439811ef8 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -305,6 +305,7 @@ set(SOURCES HTML/HTMLSourceElement.cpp HTML/HTMLSpanElement.cpp HTML/HTMLStyleElement.cpp + HTML/HTMLSummaryElement.cpp HTML/HTMLTableCaptionElement.cpp HTML/HTMLTableCellElement.cpp HTML/HTMLTableColElement.cpp diff --git a/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp b/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp index 97a1dc49ca..10867906ae 100644 --- a/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp +++ b/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp @@ -65,6 +65,7 @@ #include <LibWeb/HTML/HTMLSourceElement.h> #include <LibWeb/HTML/HTMLSpanElement.h> #include <LibWeb/HTML/HTMLStyleElement.h> +#include <LibWeb/HTML/HTMLSummaryElement.h> #include <LibWeb/HTML/HTMLTableCaptionElement.h> #include <LibWeb/HTML/HTMLTableCellElement.h> #include <LibWeb/HTML/HTMLTableColElement.h> @@ -378,6 +379,8 @@ static WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> create_html_element(JS::Re return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLSpanElement>(realm, document, move(qualified_name))); if (lowercase_tag_name == HTML::TagNames::style) return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLStyleElement>(realm, document, move(qualified_name))); + if (lowercase_tag_name == HTML::TagNames::summary) + return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLSummaryElement>(realm, document, move(qualified_name))); if (lowercase_tag_name == HTML::TagNames::caption) return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLTableCaptionElement>(realm, document, move(qualified_name))); if (lowercase_tag_name.is_one_of(Web::HTML::TagNames::td, Web::HTML::TagNames::th)) @@ -405,7 +408,7 @@ static WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> create_html_element(JS::Re if (lowercase_tag_name == HTML::TagNames::video) return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLVideoElement>(realm, document, move(qualified_name))); if (lowercase_tag_name.is_one_of( - HTML::TagNames::article, HTML::TagNames::section, HTML::TagNames::nav, HTML::TagNames::aside, HTML::TagNames::hgroup, HTML::TagNames::header, HTML::TagNames::footer, HTML::TagNames::address, HTML::TagNames::dt, HTML::TagNames::dd, HTML::TagNames::figure, HTML::TagNames::figcaption, HTML::TagNames::main, HTML::TagNames::em, HTML::TagNames::strong, HTML::TagNames::small, HTML::TagNames::s, HTML::TagNames::cite, HTML::TagNames::dfn, HTML::TagNames::abbr, HTML::TagNames::ruby, HTML::TagNames::rt, HTML::TagNames::rp, HTML::TagNames::code, HTML::TagNames::var, HTML::TagNames::samp, HTML::TagNames::kbd, HTML::TagNames::sub, HTML::TagNames::sup, HTML::TagNames::i, HTML::TagNames::b, HTML::TagNames::u, HTML::TagNames::mark, HTML::TagNames::bdi, HTML::TagNames::bdo, HTML::TagNames::wbr, HTML::TagNames::summary, HTML::TagNames::noscript, + HTML::TagNames::article, HTML::TagNames::section, HTML::TagNames::nav, HTML::TagNames::aside, HTML::TagNames::hgroup, HTML::TagNames::header, HTML::TagNames::footer, HTML::TagNames::address, HTML::TagNames::dt, HTML::TagNames::dd, HTML::TagNames::figure, HTML::TagNames::figcaption, HTML::TagNames::main, HTML::TagNames::em, HTML::TagNames::strong, HTML::TagNames::small, HTML::TagNames::s, HTML::TagNames::cite, HTML::TagNames::dfn, HTML::TagNames::abbr, HTML::TagNames::ruby, HTML::TagNames::rt, HTML::TagNames::rp, HTML::TagNames::code, HTML::TagNames::var, HTML::TagNames::samp, HTML::TagNames::kbd, HTML::TagNames::sub, HTML::TagNames::sup, HTML::TagNames::i, HTML::TagNames::b, HTML::TagNames::u, HTML::TagNames::mark, HTML::TagNames::bdi, HTML::TagNames::bdo, HTML::TagNames::wbr, HTML::TagNames::noscript, // Obsolete HTML::TagNames::acronym, HTML::TagNames::basefont, HTML::TagNames::big, HTML::TagNames::center, HTML::TagNames::nobr, HTML::TagNames::noembed, HTML::TagNames::noframes, HTML::TagNames::plaintext, HTML::TagNames::rb, HTML::TagNames::rtc, HTML::TagNames::strike, HTML::TagNames::tt)) return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLElement>(realm, document, move(qualified_name))); diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index d1f2f97aa7..e262e3cff1 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -363,6 +363,7 @@ class HTMLSlotElement; class HTMLSourceElement; class HTMLSpanElement; class HTMLStyleElement; +class HTMLSummaryElement; class HTMLTableCaptionElement; class HTMLTableCellElement; class HTMLTableColElement; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.cpp new file mode 100644 index 0000000000..40f746380d --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibWeb/Bindings/Intrinsics.h> +#include <LibWeb/HTML/HTMLDetailsElement.h> +#include <LibWeb/HTML/HTMLSummaryElement.h> + +namespace Web::HTML { + +HTMLSummaryElement::HTMLSummaryElement(DOM::Document& document, DOM::QualifiedName qualified_name) + : HTMLElement(document, move(qualified_name)) +{ + activation_behavior = [this](auto&) { + // The activation behavior of summary elements is to run the following steps: + + // 1. If this summary element is not the summary for its parent details, then return. + if (!is_summary_for_its_parent_details()) + return; + + // 2. Let parent be this summary element's parent. + auto* parent = this->parent_element(); + + // 3. If the open attribute is present on parent, then remove it. Otherwise, set parent's open attribute to the empty string. + if (parent->has_attribute(HTML::AttributeNames::open)) + parent->remove_attribute(HTML::AttributeNames::open); + else + parent->set_attribute(HTML::AttributeNames::open, "").release_value_but_fixme_should_propagate_errors(); + }; +} + +// https://html.spec.whatwg.org/multipage/interactive-elements.html#summary-for-its-parent-details +bool HTMLSummaryElement::is_summary_for_its_parent_details() +{ + // A summary element is a summary for its parent details if the following algorithm returns true: + + // 1. If this summary element has no parent, then return false. + if (!parent_element()) + return false; + + // 2. Let parent be this summary element's parent. + auto* parent = this->parent_element(); + + // 3. If parent is not a details element, then return false. + if (!is<HTMLDetailsElement>(*parent)) + return false; + + // 4. If parent's first summary element child is not this summary element, then return false. + if (parent->first_child_of_type<HTMLSummaryElement>() != this) + return false; + + // 5. Return true. + return true; +} + +HTMLSummaryElement::~HTMLSummaryElement() = default; + +JS::ThrowCompletionOr<void> HTMLSummaryElement::initialize(JS::Realm& realm) +{ + MUST_OR_THROW_OOM(Base::initialize(realm)); + + return {}; +} + +} diff --git a/Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.h b/Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.h new file mode 100644 index 0000000000..c69748ef92 --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibWeb/ARIA/Roles.h> +#include <LibWeb/HTML/HTMLElement.h> + +namespace Web::HTML { + +class HTMLSummaryElement final : public HTMLElement { + WEB_PLATFORM_OBJECT(HTMLSummaryElement, HTMLElement); + +public: + virtual ~HTMLSummaryElement() override; + + // https://www.w3.org/TR/html-aria/#el-details + virtual Optional<ARIA::Role> default_role() const override { return ARIA::Role::button; }; + + bool is_summary_for_its_parent_details(); + +private: + HTMLSummaryElement(DOM::Document&, DOM::QualifiedName); + + virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override; +}; + +} |