mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-06 08:10:02 +00:00
LibWeb: Replace webkit meter-state pseudo-elements with pseudo-classes
This also implements the `:high-value` and `:low-value` that are in the spec. Same note as before about this being based on the very-drafty CSS Forms spec. In fact, some of this isn't even in that spec yet. Specifically, the `:suboptimal-value` and `:even-less-good-value` names are undecided and subject to change. However, it's clear that this is a pseudo-class situation, not a pseudo-element one, so I think this is still an improvement, as it allows styling of the `::fill` pseudo-element regardless of what state it is in. Relevant spec issue: https://github.com/openui/open-ui/issues/1130
This commit is contained in:
parent
1978578a72
commit
d5b9c39a98
Notes:
github-actions[bot]
2025-03-19 10:10:57 +00:00
Author: https://github.com/AtkinsSJ
Commit: d5b9c39a98
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3991
6 changed files with 44 additions and 34 deletions
|
@ -122,21 +122,20 @@ meter {
|
||||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-meter-optimum-value {
|
&::fill {
|
||||||
display: block;
|
display: block;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:optimal-value::fill {
|
||||||
background-color: hsl(141, 53%, 53%);
|
background-color: hsl(141, 53%, 53%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-meter-suboptimum-value {
|
&:suboptimal-value::fill {
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
background-color: hsl(48, 100%, 67%);
|
background-color: hsl(48, 100%, 67%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-meter-even-less-good-value {
|
&:even-less-good-value::fill {
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
background-color: hsl(348, 100%, 61%);
|
background-color: hsl(348, 100%, 61%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"argument": ""
|
"argument": ""
|
||||||
},
|
},
|
||||||
|
"even-less-good-value": {
|
||||||
|
"argument": ""
|
||||||
|
},
|
||||||
"first-child": {
|
"first-child": {
|
||||||
"argument": ""
|
"argument": ""
|
||||||
},
|
},
|
||||||
|
@ -44,6 +47,9 @@
|
||||||
"has": {
|
"has": {
|
||||||
"argument": "<relative-selector-list>"
|
"argument": "<relative-selector-list>"
|
||||||
},
|
},
|
||||||
|
"high-value": {
|
||||||
|
"argument": ""
|
||||||
|
},
|
||||||
"host": {
|
"host": {
|
||||||
"argument": "<compound-selector>?"
|
"argument": "<compound-selector>?"
|
||||||
},
|
},
|
||||||
|
@ -74,6 +80,9 @@
|
||||||
"local-link": {
|
"local-link": {
|
||||||
"argument": ""
|
"argument": ""
|
||||||
},
|
},
|
||||||
|
"low-value": {
|
||||||
|
"argument": ""
|
||||||
|
},
|
||||||
"modal": {
|
"modal": {
|
||||||
"argument": ""
|
"argument": ""
|
||||||
},
|
},
|
||||||
|
@ -104,6 +113,9 @@
|
||||||
"open": {
|
"open": {
|
||||||
"argument": ""
|
"argument": ""
|
||||||
},
|
},
|
||||||
|
"optimal-value": {
|
||||||
|
"argument": ""
|
||||||
|
},
|
||||||
"popover-open": {
|
"popover-open": {
|
||||||
"argument": ""
|
"argument": ""
|
||||||
},
|
},
|
||||||
|
@ -134,6 +146,9 @@
|
||||||
"stalled": {
|
"stalled": {
|
||||||
"argument": ""
|
"argument": ""
|
||||||
},
|
},
|
||||||
|
"suboptimal-value": {
|
||||||
|
"argument": ""
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"argument": ""
|
"argument": ""
|
||||||
},
|
},
|
||||||
|
|
|
@ -554,12 +554,6 @@ StringView Selector::PseudoElement::name(Selector::PseudoElement::Type pseudo_el
|
||||||
return "fill"sv;
|
return "fill"sv;
|
||||||
case Selector::PseudoElement::Type::Thumb:
|
case Selector::PseudoElement::Type::Thumb:
|
||||||
return "thumb"sv;
|
return "thumb"sv;
|
||||||
case Selector::PseudoElement::Type::MeterEvenLessGoodValue:
|
|
||||||
return "-webkit-meter-even-less-good-value"sv;
|
|
||||||
case Selector::PseudoElement::Type::MeterOptimumValue:
|
|
||||||
return "-webkit-meter-optimum-value"sv;
|
|
||||||
case Selector::PseudoElement::Type::MeterSuboptimumValue:
|
|
||||||
return "-webkit-meter-suboptimum-value"sv;
|
|
||||||
case Selector::PseudoElement::Type::Placeholder:
|
case Selector::PseudoElement::Type::Placeholder:
|
||||||
return "placeholder"sv;
|
return "placeholder"sv;
|
||||||
case Selector::PseudoElement::Type::Selection:
|
case Selector::PseudoElement::Type::Selection:
|
||||||
|
@ -595,12 +589,6 @@ Optional<Selector::PseudoElement> Selector::PseudoElement::from_string(FlyString
|
||||||
return Selector::PseudoElement { Selector::PseudoElement::Type::Fill };
|
return Selector::PseudoElement { Selector::PseudoElement::Type::Fill };
|
||||||
} else if (name.equals_ignoring_ascii_case("thumb"sv)) {
|
} else if (name.equals_ignoring_ascii_case("thumb"sv)) {
|
||||||
return Selector::PseudoElement { Selector::PseudoElement::Type::Thumb };
|
return Selector::PseudoElement { Selector::PseudoElement::Type::Thumb };
|
||||||
} else if (name.equals_ignoring_ascii_case("-webkit-meter-even-less-good-value"sv)) {
|
|
||||||
return Selector::PseudoElement { Selector::PseudoElement::Type::MeterEvenLessGoodValue };
|
|
||||||
} else if (name.equals_ignoring_ascii_case("-webkit-meter-optimum-value"sv)) {
|
|
||||||
return Selector::PseudoElement { Selector::PseudoElement::Type::MeterOptimumValue };
|
|
||||||
} else if (name.equals_ignoring_ascii_case("-webkit-meter-suboptimum-value"sv)) {
|
|
||||||
return Selector::PseudoElement { Selector::PseudoElement::Type::MeterSuboptimumValue };
|
|
||||||
} else if (name.equals_ignoring_ascii_case("placeholder"sv)) {
|
} else if (name.equals_ignoring_ascii_case("placeholder"sv)) {
|
||||||
return Selector::PseudoElement { Selector::PseudoElement::Type::Placeholder };
|
return Selector::PseudoElement { Selector::PseudoElement::Type::Placeholder };
|
||||||
} else if (name.equals_ignoring_ascii_case("selection"sv)) {
|
} else if (name.equals_ignoring_ascii_case("selection"sv)) {
|
||||||
|
|
|
@ -33,9 +33,6 @@ public:
|
||||||
Track,
|
Track,
|
||||||
Fill,
|
Fill,
|
||||||
Thumb,
|
Thumb,
|
||||||
MeterEvenLessGoodValue,
|
|
||||||
MeterOptimumValue,
|
|
||||||
MeterSuboptimumValue,
|
|
||||||
Placeholder,
|
Placeholder,
|
||||||
Selection,
|
Selection,
|
||||||
Backdrop,
|
Backdrop,
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <LibWeb/HTML/HTMLHtmlElement.h>
|
#include <LibWeb/HTML/HTMLHtmlElement.h>
|
||||||
#include <LibWeb/HTML/HTMLInputElement.h>
|
#include <LibWeb/HTML/HTMLInputElement.h>
|
||||||
#include <LibWeb/HTML/HTMLMediaElement.h>
|
#include <LibWeb/HTML/HTMLMediaElement.h>
|
||||||
|
#include <LibWeb/HTML/HTMLMeterElement.h>
|
||||||
#include <LibWeb/HTML/HTMLProgressElement.h>
|
#include <LibWeb/HTML/HTMLProgressElement.h>
|
||||||
#include <LibWeb/HTML/HTMLSelectElement.h>
|
#include <LibWeb/HTML/HTMLSelectElement.h>
|
||||||
#include <LibWeb/HTML/HTMLTextAreaElement.h>
|
#include <LibWeb/HTML/HTMLTextAreaElement.h>
|
||||||
|
@ -423,6 +424,13 @@ static inline bool matches_host_pseudo_class(GC::Ref<DOM::Element const> element
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool matches_optimal_value_pseudo_class(DOM::Element const& element, HTML::HTMLMeterElement::ValueState desired_state)
|
||||||
|
{
|
||||||
|
if (auto* meter = as_if<HTML::HTMLMeterElement>(element))
|
||||||
|
return meter->value_state() == desired_state;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoClassSelector const& pseudo_class, DOM::Element const& element, GC::Ptr<DOM::Element const> shadow_host, MatchContext& context, GC::Ptr<DOM::ParentNode const> scope, SelectorKind selector_kind)
|
static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoClassSelector const& pseudo_class, DOM::Element const& element, GC::Ptr<DOM::Element const> shadow_host, MatchContext& context, GC::Ptr<DOM::ParentNode const> scope, SelectorKind selector_kind)
|
||||||
{
|
{
|
||||||
switch (pseudo_class.type) {
|
switch (pseudo_class.type) {
|
||||||
|
@ -502,6 +510,20 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
|
||||||
return element.matches_checked_pseudo_class();
|
return element.matches_checked_pseudo_class();
|
||||||
case CSS::PseudoClass::Indeterminate:
|
case CSS::PseudoClass::Indeterminate:
|
||||||
return matches_indeterminate_pseudo_class(element);
|
return matches_indeterminate_pseudo_class(element);
|
||||||
|
case CSS::PseudoClass::HighValue:
|
||||||
|
if (auto* meter = as_if<HTML::HTMLMeterElement>(element))
|
||||||
|
return meter->value() > meter->high();
|
||||||
|
return false;
|
||||||
|
case CSS::PseudoClass::LowValue:
|
||||||
|
if (auto* meter = as_if<HTML::HTMLMeterElement>(element))
|
||||||
|
return meter->value() < meter->low();
|
||||||
|
return false;
|
||||||
|
case CSS::PseudoClass::OptimalValue:
|
||||||
|
return matches_optimal_value_pseudo_class(element, HTML::HTMLMeterElement::ValueState::Optimal);
|
||||||
|
case CSS::PseudoClass::SuboptimalValue:
|
||||||
|
return matches_optimal_value_pseudo_class(element, HTML::HTMLMeterElement::ValueState::Suboptimal);
|
||||||
|
case CSS::PseudoClass::EvenLessGoodValue:
|
||||||
|
return matches_optimal_value_pseudo_class(element, HTML::HTMLMeterElement::ValueState::EvenLessGood);
|
||||||
case CSS::PseudoClass::Defined:
|
case CSS::PseudoClass::Defined:
|
||||||
return element.is_defined();
|
return element.is_defined();
|
||||||
case CSS::PseudoClass::Has:
|
case CSS::PseudoClass::Has:
|
||||||
|
|
|
@ -201,6 +201,7 @@ void HTMLMeterElement::create_shadow_tree_if_needed()
|
||||||
MUST(shadow_root->append_child(*meter_bar_element));
|
MUST(shadow_root->append_child(*meter_bar_element));
|
||||||
|
|
||||||
m_meter_value_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML));
|
m_meter_value_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML));
|
||||||
|
m_meter_value_element->set_use_pseudo_element(CSS::Selector::PseudoElement::Type::Fill);
|
||||||
MUST(meter_bar_element->append_child(*m_meter_value_element));
|
MUST(meter_bar_element->append_child(*m_meter_value_element));
|
||||||
update_meter_value_element();
|
update_meter_value_element();
|
||||||
}
|
}
|
||||||
|
@ -242,18 +243,6 @@ void HTMLMeterElement::update_meter_value_element()
|
||||||
if (!m_meter_value_element)
|
if (!m_meter_value_element)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (m_cached_value_state) {
|
|
||||||
case ValueState::Optimal:
|
|
||||||
m_meter_value_element->set_use_pseudo_element(CSS::Selector::PseudoElement::Type::MeterOptimumValue);
|
|
||||||
break;
|
|
||||||
case ValueState::Suboptimal:
|
|
||||||
m_meter_value_element->set_use_pseudo_element(CSS::Selector::PseudoElement::Type::MeterSuboptimumValue);
|
|
||||||
break;
|
|
||||||
case ValueState::EvenLessGood:
|
|
||||||
m_meter_value_element->set_use_pseudo_element(CSS::Selector::PseudoElement::Type::MeterEvenLessGoodValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
double position = (value - min) / (max - min) * 100;
|
double position = (value - min) / (max - min) * 100;
|
||||||
MUST(m_meter_value_element->style_for_bindings()->set_property(CSS::PropertyID::Width, MUST(String::formatted("{}%", position))));
|
MUST(m_meter_value_element->style_for_bindings()->set_property(CSS::PropertyID::Width, MUST(String::formatted("{}%", position))));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue