LibWeb: Implement ::details-content pseudo element

Details' contents matches a new details-content pseudo element.

Further work is required to make this pseudo-element behave per spec.

This pseudo should be element-backed per
https://drafts.csswg.org/css-pseudo/#element-backed
This commit is contained in:
Luke Warlow 2024-11-30 23:46:26 +00:00 committed by Tim Ledbetter
parent 2249f09267
commit b17bbe6d1f
Notes: github-actions[bot] 2024-12-06 07:17:31 +00:00
7 changed files with 89 additions and 3 deletions

View file

@ -520,6 +520,8 @@ StringView Selector::PseudoElement::name(Selector::PseudoElement::Type pseudo_el
return "backdrop"sv;
case Selector::PseudoElement::Type::FileSelectorButton:
return "file-selector-button"sv;
case Selector::PseudoElement::Type::DetailsContent:
return "details-content"sv;
case Selector::PseudoElement::Type::KnownPseudoElementCount:
break;
case Selector::PseudoElement::Type::UnknownWebKit:
@ -560,6 +562,8 @@ Optional<Selector::PseudoElement> Selector::PseudoElement::from_string(FlyString
return Selector::PseudoElement { Selector::PseudoElement::Type::Backdrop };
} else if (name.equals_ignoring_ascii_case("file-selector-button"sv)) {
return Selector::PseudoElement { Selector::PseudoElement::Type::FileSelectorButton };
} else if (name.equals_ignoring_ascii_case("details-content"sv)) {
return Selector::PseudoElement { Selector::PseudoElement::Type::DetailsContent };
} else if (name.equals_ignoring_ascii_case("-webkit-slider-runnable-track"sv)) {
return Selector::PseudoElement { Selector::PseudoElement::Type::SliderRunnableTrack };
} else if (name.equals_ignoring_ascii_case("-webkit-slider-thumb"sv)) {

View file

@ -42,6 +42,7 @@ public:
SliderThumb,
Backdrop,
FileSelectorButton,
DetailsContent,
// Keep this last.
KnownPseudoElementCount,

View file

@ -124,18 +124,33 @@ WebIDL::ExceptionOr<void> HTMLDetailsElement::create_shadow_tree_if_needed()
auto& realm = this->realm();
// The element is also expected to have an internal shadow tree with two slots.
// The details element is expected to have an internal shadow tree with three child elements:
auto shadow_root = realm.create<DOM::ShadowRoot>(document(), *this, Bindings::ShadowRootMode::Closed);
shadow_root->set_slot_assignment(Bindings::SlotAssignmentMode::Manual);
// The first slot is expected to take the details element's first summary element child, if any.
// The first child element is a slot that is expected to take the details element's first summary element child, if any.
auto summary_slot = TRY(DOM::create_element(document(), HTML::TagNames::slot, Namespace::HTML));
MUST(shadow_root->append_child(summary_slot));
// The second slot is expected to take the details element's remaining descendants, if any.
// The second child element is a slot that is expected to take the details element's remaining descendants, if any.
auto descendants_slot = TRY(DOM::create_element(document(), HTML::TagNames::slot, Namespace::HTML));
descendants_slot->set_use_pseudo_element(CSS::Selector::PseudoElement::Type::DetailsContent);
MUST(shadow_root->append_child(descendants_slot));
// The third child element is either a link or style element with the following styles for the default summary:
auto style = TRY(DOM::create_element(document(), HTML::TagNames::style, Namespace::HTML));
style->set_text_content(R"~~~(
:host summary {
display: list-item;
counter-increment: list-item 0;
list-style: disclosure-closed inside;
}
:host([open]) summary {
list-style-type: disclosure-open;
}
)~~~"_string);
MUST(shadow_root->append_child(style));
m_summary_slot = static_cast<HTML::HTMLSlotElement&>(*summary_slot);
m_descendants_slot = static_cast<HTML::HTMLSlotElement&>(*descendants_slot);
set_shadow_root(shadow_root);

View file

@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<title>Details pseudo-elements</title>
<style>
div { background: aqua }
</style>
<details open>
<summary>The summary</summary>
<div>The details!</div>
</details>

View file

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<title>::details-content pseudo element is display: block</title>
<style>
#contents { opacity: 0.5; }
details
</style>
<div>
<div>summary</div>
<div id="contents">contents</div>
</div>

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<title>Details pseudo-elements</title>
<link rel="match" href="../../../../../expected/wpt-import/html/rendering/the-details-element/details-pseudo-elements-001-ref.html">
<link rel="help" href="https://github.com/whatwg/html/pull/10265">
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#details-content-pseudo">
<link rel="help" href="https://github.com/dbaron/details-styling">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1469418">
<style>
details::details-content {
background: aqua;
display: block; /* override display: contents for slot */
}
</style>
<details open>
<summary>The summary</summary>
<div>The details!</div>
</details>

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<title>::details-content pseudo element is display: block</title>
<link rel="match" href="../../../../../expected/wpt-import/html/rendering/the-details-element/details-pseudo-elements-003-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#details-content-pseudo">
<link rel="help" href="https://github.com/whatwg/html/pull/10265">
<link rel="help" href="https://github.com/dbaron/details-styling">
<link rel="help" href="https://crbug.com/1469418">
<style>
summary { display: block }
details::details-content { opacity: 0.5; }
details
</style>
<details open>
<summary>summary</summary>
contents
</details>