summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstelar7 <dudedbz@gmail.com>2023-06-02 21:08:14 +0200
committerAndreas Kling <kling@serenityos.org>2023-06-03 05:56:00 +0200
commit8773122f6b55044a738dcc22e4342d3de4c4c25d (patch)
tree6d2d19d58f06dc2817131a1e3d3422c139696300
parent870bcd56df13a0a6123c0d15228105e31b7292a6 (diff)
downloadserenity-8773122f6b55044a738dcc22e4342d3de4c4c25d.zip
LibWeb: Implement the <summary> element
-rw-r--r--Userland/Libraries/LibWeb/CMakeLists.txt1
-rw-r--r--Userland/Libraries/LibWeb/DOM/ElementFactory.cpp5
-rw-r--r--Userland/Libraries/LibWeb/Forward.h1
-rw-r--r--Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.cpp67
-rw-r--r--Userland/Libraries/LibWeb/HTML/HTMLSummaryElement.h31
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;
+};
+
+}