mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 12:23:15 +00:00
LibWeb: Implement the :open and :closed pseudo-classes
These apply to any elements that have some kind of open/closed state. The spec suggests `<details>`, `<dialog>`, and `<select>`, so that's what I've supported here. Only `<details>` is fleshed out right now, but once the others are, these pseudo-classes should work automatically. :^)
This commit is contained in:
parent
29bb0f0ae6
commit
6bf107fc16
18
Tests/LibWeb/Ref/css-open-closed-selectors.html
Normal file
18
Tests/LibWeb/Ref/css-open-closed-selectors.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!doctype html>
|
||||
<link rel="match" href="reference/css-open-closed-selectors-ref.html" />
|
||||
<style>
|
||||
:open {
|
||||
color: green;
|
||||
}
|
||||
:closed {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<details open>
|
||||
<summary>Hi</summary>
|
||||
Well hello friends!
|
||||
</details>
|
||||
<details>
|
||||
<summary>Hi</summary>
|
||||
Well hello friends!
|
||||
</details>
|
|
@ -0,0 +1,17 @@
|
|||
<!doctype html>
|
||||
<style>
|
||||
.open {
|
||||
color: green;
|
||||
}
|
||||
.closed {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<details open class="open">
|
||||
<summary>Hi</summary>
|
||||
Well hello friends!
|
||||
</details>
|
||||
<details class="closed">
|
||||
<summary>Hi</summary>
|
||||
Well hello friends!
|
||||
</details>
|
|
@ -11,6 +11,9 @@
|
|||
"checked": {
|
||||
"argument": ""
|
||||
},
|
||||
"closed": {
|
||||
"argument": ""
|
||||
},
|
||||
"defined": {
|
||||
"argument": ""
|
||||
},
|
||||
|
@ -92,6 +95,9 @@
|
|||
"only-of-type": {
|
||||
"argument": ""
|
||||
},
|
||||
"open": {
|
||||
"argument": ""
|
||||
},
|
||||
"paused": {
|
||||
"argument": ""
|
||||
},
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include <LibWeb/HTML/HTMLAnchorElement.h>
|
||||
#include <LibWeb/HTML/HTMLAreaElement.h>
|
||||
#include <LibWeb/HTML/HTMLButtonElement.h>
|
||||
#include <LibWeb/HTML/HTMLDetailsElement.h>
|
||||
#include <LibWeb/HTML/HTMLDialogElement.h>
|
||||
#include <LibWeb/HTML/HTMLFieldSetElement.h>
|
||||
#include <LibWeb/HTML/HTMLHtmlElement.h>
|
||||
#include <LibWeb/HTML/HTMLInputElement.h>
|
||||
|
@ -238,6 +240,24 @@ static bool matches_read_write_pseudo_class(DOM::Element const& element)
|
|||
return element.is_editable();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/selectors-4/#open-state
|
||||
static bool matches_open_state_pseudo_class(DOM::Element const& element, bool open)
|
||||
{
|
||||
// The :open pseudo-class represents an element that has both “open” and “closed” states,
|
||||
// and which is currently in the “open” state.
|
||||
// The :closed pseudo-class represents an element that has both “open” and “closed” states,
|
||||
// and which is currently in the closed state.
|
||||
|
||||
// NOTE: Spec specifically suggests supporting <details>, <dialog>, and <select>.
|
||||
// There may be others we want to treat as open or closed.
|
||||
if (is<HTML::HTMLDetailsElement>(element) || is<HTML::HTMLDialogElement>(element))
|
||||
return open == element.has_attribute(HTML::AttributeNames::open);
|
||||
if (is<HTML::HTMLSelectElement>(element))
|
||||
return open == static_cast<HTML::HTMLSelectElement const&>(element).is_open();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoClassSelector const& pseudo_class, Optional<CSS::CSSStyleSheet const&> style_sheet_for_rule, DOM::Element const& element, JS::GCPtr<DOM::ParentNode const> scope)
|
||||
{
|
||||
switch (pseudo_class.type) {
|
||||
|
@ -509,6 +529,9 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
|
|||
// - FIXME: textarea elements that have a placeholder attribute whose value is currently being presented to the user.
|
||||
return false;
|
||||
}
|
||||
case CSS::PseudoClass::Open:
|
||||
case CSS::PseudoClass::Closed:
|
||||
return matches_open_state_pseudo_class(element, pseudo_class.type == CSS::PseudoClass::Open);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue