1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:58:11 +00:00

LibWeb: Implement the <summary> element

This commit is contained in:
stelar7 2023-06-02 21:08:14 +02:00 committed by Andreas Kling
parent 870bcd56df
commit 8773122f6b
5 changed files with 104 additions and 1 deletions

View file

@ -305,6 +305,7 @@ set(SOURCES
HTML/HTMLSourceElement.cpp HTML/HTMLSourceElement.cpp
HTML/HTMLSpanElement.cpp HTML/HTMLSpanElement.cpp
HTML/HTMLStyleElement.cpp HTML/HTMLStyleElement.cpp
HTML/HTMLSummaryElement.cpp
HTML/HTMLTableCaptionElement.cpp HTML/HTMLTableCaptionElement.cpp
HTML/HTMLTableCellElement.cpp HTML/HTMLTableCellElement.cpp
HTML/HTMLTableColElement.cpp HTML/HTMLTableColElement.cpp

View file

@ -65,6 +65,7 @@
#include <LibWeb/HTML/HTMLSourceElement.h> #include <LibWeb/HTML/HTMLSourceElement.h>
#include <LibWeb/HTML/HTMLSpanElement.h> #include <LibWeb/HTML/HTMLSpanElement.h>
#include <LibWeb/HTML/HTMLStyleElement.h> #include <LibWeb/HTML/HTMLStyleElement.h>
#include <LibWeb/HTML/HTMLSummaryElement.h>
#include <LibWeb/HTML/HTMLTableCaptionElement.h> #include <LibWeb/HTML/HTMLTableCaptionElement.h>
#include <LibWeb/HTML/HTMLTableCellElement.h> #include <LibWeb/HTML/HTMLTableCellElement.h>
#include <LibWeb/HTML/HTMLTableColElement.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))); return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLSpanElement>(realm, document, move(qualified_name)));
if (lowercase_tag_name == HTML::TagNames::style) if (lowercase_tag_name == HTML::TagNames::style)
return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLStyleElement>(realm, document, move(qualified_name))); 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) if (lowercase_tag_name == HTML::TagNames::caption)
return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLTableCaptionElement>(realm, document, move(qualified_name))); 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)) 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) if (lowercase_tag_name == HTML::TagNames::video)
return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLVideoElement>(realm, document, move(qualified_name))); return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLVideoElement>(realm, document, move(qualified_name)));
if (lowercase_tag_name.is_one_of( 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 // 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)) 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))); return MUST_OR_THROW_OOM(realm.heap().allocate<HTML::HTMLElement>(realm, document, move(qualified_name)));

View file

@ -363,6 +363,7 @@ class HTMLSlotElement;
class HTMLSourceElement; class HTMLSourceElement;
class HTMLSpanElement; class HTMLSpanElement;
class HTMLStyleElement; class HTMLStyleElement;
class HTMLSummaryElement;
class HTMLTableCaptionElement; class HTMLTableCaptionElement;
class HTMLTableCellElement; class HTMLTableCellElement;
class HTMLTableColElement; class HTMLTableColElement;

View file

@ -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 {};
}
}

View file

@ -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;
};
}