LibWeb: Implement the CSS all
property
This sets all longhand values to one of initial, inherit, unset or revert. Note that revert is not supported yet, but will be soon.
This commit is contained in:
parent
de31a8a425
commit
13d5d47b56
Notes:
sideshowbarker
2024-07-17 07:16:27 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/13d5d47b56 Pull-request: https://github.com/SerenityOS/serenity/pull/20253 Reviewed-by: https://github.com/ADKaster Reviewed-by: https://github.com/AtkinsSJ
5 changed files with 62 additions and 2 deletions
|
@ -105,6 +105,7 @@ namespace Web::CSS {
|
|||
enum class PropertyID {
|
||||
Invalid,
|
||||
Custom,
|
||||
All,
|
||||
)~~~"));
|
||||
|
||||
Vector<DeprecatedString> shorthand_property_ids;
|
||||
|
@ -361,6 +362,8 @@ Optional<PropertyID> property_id_from_camel_case_string(StringView string)
|
|||
|
||||
Optional<PropertyID> property_id_from_string(StringView string)
|
||||
{
|
||||
if (Infra::is_ascii_case_insensitive_match(string, "all"sv))
|
||||
return PropertyID::All;
|
||||
)~~~"));
|
||||
|
||||
TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> {
|
||||
|
|
12
Tests/LibWeb/Layout/expected/css-all-unset.txt
Normal file
12
Tests/LibWeb/Layout/expected/css-all-unset.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: inline
|
||||
line 0 width: 238.125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 1, length: 18, rect: [0,0 134.984375x17.46875]
|
||||
"* { all: unset; } "
|
||||
frag 1 from TextNode start: 0, length: 13, rect: [134.984375,0 103.140625x17.46875]
|
||||
"Hello friends"
|
||||
InlineNode <html>
|
||||
InlineNode <head>
|
||||
InlineNode <style>
|
||||
TextNode <#text>
|
||||
InlineNode <body>
|
||||
TextNode <#text>
|
3
Tests/LibWeb/Layout/input/css-all-unset.html
Normal file
3
Tests/LibWeb/Layout/input/css-all-unset.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<!doctype html><style>
|
||||
* { all: unset; }
|
||||
</style>Hello friends
|
|
@ -83,6 +83,9 @@ struct Traits<Web::CSS::FontFaceKey> : public GenericTraits<Web::CSS::FontFaceKe
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
static DOM::Element const* element_to_inherit_style_from(DOM::Element const*, Optional<CSS::Selector::PseudoElement>);
|
||||
static NonnullRefPtr<StyleValue const> get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID, DOM::Element const*, Optional<CSS::Selector::PseudoElement>);
|
||||
|
||||
StyleComputer::StyleComputer(DOM::Document& document)
|
||||
: m_document(document)
|
||||
, m_default_font_metrics(16, Gfx::FontDatabase::default_font().pixel_metrics(), 16)
|
||||
|
@ -830,6 +833,31 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
|
|||
style.set_property(property_id, value, declaration);
|
||||
}
|
||||
|
||||
void StyleComputer::set_all_properties(DOM::Element& element, Optional<CSS::Selector::PseudoElement> pseudo_element, StyleProperties& style, StyleValue const& value, DOM::Document& document, CSS::CSSStyleDeclaration const* declaration) const
|
||||
{
|
||||
for (auto i = to_underlying(CSS::first_longhand_property_id); i <= to_underlying(CSS::last_longhand_property_id); ++i) {
|
||||
auto property_id = (CSS::PropertyID)i;
|
||||
|
||||
if (value.is_unset()) {
|
||||
if (is_inherited_property(property_id))
|
||||
style.m_property_values[to_underlying(property_id)] = { { get_inherit_value(document.realm(), property_id, &element, pseudo_element), nullptr } };
|
||||
else
|
||||
style.m_property_values[to_underlying(property_id)] = { { property_initial_value(document.realm(), property_id).release_value_but_fixme_should_propagate_errors(), nullptr } };
|
||||
continue;
|
||||
}
|
||||
|
||||
NonnullRefPtr<StyleValue> property_value = value;
|
||||
if (property_value->is_unresolved()) {
|
||||
if (auto resolved = resolve_unresolved_style_value(element, pseudo_element, property_id, property_value->as_unresolved()))
|
||||
property_value = resolved.release_nonnull();
|
||||
}
|
||||
if (!property_value->is_unresolved())
|
||||
set_property_expanding_shorthands(style, property_id, property_value, document, declaration);
|
||||
|
||||
set_property_expanding_shorthands(style, property_id, value, document, declaration);
|
||||
}
|
||||
}
|
||||
|
||||
static RefPtr<StyleValue const> get_custom_property(DOM::Element const& element, Optional<CSS::Selector::PseudoElement> pseudo_element, FlyString const& custom_property_name)
|
||||
{
|
||||
if (pseudo_element.has_value()) {
|
||||
|
@ -1054,6 +1082,12 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e
|
|||
for (auto const& property : verify_cast<PropertyOwningCSSStyleDeclaration>(match.rule->declaration()).properties()) {
|
||||
if (important != property.important)
|
||||
continue;
|
||||
|
||||
if (property.property_id == CSS::PropertyID::All) {
|
||||
set_all_properties(element, pseudo_element, style, property.value, m_document, &match.rule->declaration());
|
||||
continue;
|
||||
}
|
||||
|
||||
auto property_value = property.value;
|
||||
if (property.value->is_unresolved()) {
|
||||
if (auto resolved = resolve_unresolved_style_value(element, pseudo_element, property.property_id, property.value->as_unresolved()))
|
||||
|
@ -1069,6 +1103,12 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e
|
|||
for (auto const& property : inline_style->properties()) {
|
||||
if (important != property.important)
|
||||
continue;
|
||||
|
||||
if (property.property_id == CSS::PropertyID::All) {
|
||||
set_all_properties(element, pseudo_element, style, property.value, m_document, inline_style);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto property_value = property.value;
|
||||
if (property.value->is_unresolved()) {
|
||||
if (auto resolved = resolve_unresolved_style_value(element, pseudo_element, property.property_id, property.value->as_unresolved()))
|
||||
|
@ -1804,7 +1844,7 @@ ErrorOr<void> StyleComputer::compute_cascaded_values(StyleProperties& style, DOM
|
|||
return {};
|
||||
}
|
||||
|
||||
static DOM::Element const* element_to_inherit_style_from(DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element)
|
||||
DOM::Element const* element_to_inherit_style_from(DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element)
|
||||
{
|
||||
// Pseudo-elements treat their originating element as their parent.
|
||||
DOM::Element const* parent_element = nullptr;
|
||||
|
@ -1816,7 +1856,7 @@ static DOM::Element const* element_to_inherit_style_from(DOM::Element const* ele
|
|||
return parent_element;
|
||||
}
|
||||
|
||||
static NonnullRefPtr<StyleValue const> get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID property_id, DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element)
|
||||
NonnullRefPtr<StyleValue const> get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID property_id, DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element)
|
||||
{
|
||||
auto* parent_element = element_to_inherit_style_from(element, pseudo_element);
|
||||
|
||||
|
|
|
@ -154,6 +154,8 @@ private:
|
|||
bool expand_variables(DOM::Element&, Optional<CSS::Selector::PseudoElement>, StringView property_name, HashMap<FlyString, NonnullRefPtr<PropertyDependencyNode>>& dependencies, Parser::TokenStream<Parser::ComponentValue>& source, Vector<Parser::ComponentValue>& dest) const;
|
||||
bool expand_unresolved_values(DOM::Element&, StringView property_name, Parser::TokenStream<Parser::ComponentValue>& source, Vector<Parser::ComponentValue>& dest) const;
|
||||
|
||||
void set_all_properties(DOM::Element&, Optional<CSS::Selector::PseudoElement>, StyleProperties&, StyleValue const&, DOM::Document&, CSS::CSSStyleDeclaration const*) const;
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_stylesheet(CascadeOrigin, Callback) const;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue