Skip to content

Commit 4a0ac31

Browse files
GingehAtkinsSJ
authored andcommitted
LibWeb: Obtain theme-color on meta element removal and modification
1 parent df70455 commit 4a0ac31

File tree

3 files changed

+55
-35
lines changed

3 files changed

+55
-35
lines changed

Libraries/LibWeb/DOM/Document.cpp

+47
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,53 @@ void Document::obtain_supported_color_schemes()
14711471
// 3. Return null.
14721472
}
14731473

1474+
// https://html.spec.whatwg.org/multipage/semantics.html#meta-theme-color
1475+
void Document::obtain_theme_color()
1476+
{
1477+
Color theme_color = Color::Transparent;
1478+
1479+
// 1. Let candidate elements be the list of all meta elements that meet the following criteria, in tree order:
1480+
for_each_in_subtree_of_type<HTML::HTMLMetaElement>([&](HTML::HTMLMetaElement& element) {
1481+
// * the element is in a document tree;
1482+
// * the element has a name attribute, whose value is an ASCII case-insensitive match for theme-color; and
1483+
// * the element has a content attribute.
1484+
1485+
// 2. For each element in candidate elements:
1486+
auto content = element.attribute(HTML::AttributeNames::content);
1487+
if (element.name().has_value() && element.name()->equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) {
1488+
// 1. If element has a media attribute and the value of element's media attribute does not match the environment, then continue.
1489+
auto context = CSS::Parser::ParsingContext { document() };
1490+
auto media = element.attribute(HTML::AttributeNames::media);
1491+
if (media.has_value()) {
1492+
auto query = parse_media_query(context, media.value());
1493+
if (window() && !query->evaluate(*window()))
1494+
return TraversalDecision::Continue;
1495+
}
1496+
1497+
// 2. Let value be the result of stripping leading and trailing ASCII whitespace from the value of element's content attribute.
1498+
auto value = content->bytes_as_string_view().trim(Infra::ASCII_WHITESPACE);
1499+
1500+
// 3. Let color be the result of parsing value.
1501+
auto css_value = parse_css_value(context, value, CSS::PropertyID::Color);
1502+
1503+
// 4. If color is not failure, then return color.
1504+
if (!css_value.is_null() && css_value->is_color()) {
1505+
Optional<Layout::NodeWithStyle const&> root_node;
1506+
if (html_element())
1507+
root_node = *html_element()->layout_node();
1508+
1509+
theme_color = css_value->to_color(root_node);
1510+
return TraversalDecision::Break;
1511+
}
1512+
}
1513+
1514+
return TraversalDecision::Continue;
1515+
});
1516+
1517+
// 3. Return nothing(the page has no theme color).
1518+
document().page().client().page_did_change_theme_color(theme_color);
1519+
}
1520+
14741521
Layout::Viewport const* Document::layout_node() const
14751522
{
14761523
return static_cast<Layout::Viewport const*>(Node::layout_node());

Libraries/LibWeb/DOM/Document.h

+2
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ class Document
245245
Optional<Vector<String> const&> supported_color_schemes() const;
246246
void obtain_supported_color_schemes();
247247

248+
void obtain_theme_color();
249+
248250
void update_style();
249251
void update_layout();
250252
void update_paint_and_hit_testing_properties_if_needed();

Libraries/LibWeb/HTML/HTMLMetaElement.cpp

+6-35
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,18 @@ Optional<HTMLMetaElement::HttpEquivAttributeState> HTMLMetaElement::http_equiv_s
5151
void HTMLMetaElement::update_metadata(Optional<String> const& old_name)
5252
{
5353
if (name().has_value()) {
54-
if (name()->equals_ignoring_ascii_case("color-scheme"sv)) {
54+
if (name()->equals_ignoring_ascii_case("theme-color"sv)) {
55+
document().obtain_theme_color();
56+
} else if (name()->equals_ignoring_ascii_case("color-scheme"sv)) {
5557
document().obtain_supported_color_schemes();
5658
return;
5759
}
5860
}
5961

6062
if (old_name.has_value()) {
61-
if (old_name->equals_ignoring_ascii_case("color-scheme"sv)) {
63+
if (old_name->equals_ignoring_ascii_case("theme-color"sv)) {
64+
document().obtain_theme_color();
65+
} else if (old_name->equals_ignoring_ascii_case("color-scheme"sv)) {
6266
document().obtain_supported_color_schemes();
6367
return;
6468
}
@@ -69,39 +73,6 @@ void HTMLMetaElement::inserted()
6973
{
7074
Base::inserted();
7175

72-
// https://html.spec.whatwg.org/multipage/semantics.html#meta-theme-color
73-
// 1. To obtain a page's theme color, user agents must run the following steps:
74-
// * The element is in a document tree
75-
// * The element has a name attribute, whose value is an ASCII case-insensitive match for theme-color
76-
// * The element has a content attribute
77-
auto content = attribute(AttributeNames::content);
78-
if (name().has_value() && name()->equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) {
79-
auto context = CSS::Parser::ParsingContext { document() };
80-
81-
// 2. For each element in candidate elements:
82-
83-
// 1. If element has a media attribute and the value of element's media attribute does not match the environment, then continue.
84-
auto media = attribute(AttributeNames::media);
85-
if (media.has_value()) {
86-
auto query = parse_media_query(context, media.value());
87-
if (document().window() && !query->evaluate(*document().window()))
88-
return;
89-
}
90-
91-
// 2. Let value be the result of stripping leading and trailing ASCII whitespace from the value of element's content attribute.
92-
auto value = content->bytes_as_string_view().trim(Infra::ASCII_WHITESPACE);
93-
94-
// 3. Let color be the result of parsing value.
95-
auto css_value = parse_css_value(context, value, CSS::PropertyID::Color);
96-
if (css_value.is_null() || !css_value->is_color())
97-
return;
98-
auto color = css_value->to_color({}); // TODO: Pass a layout node?
99-
100-
// 4. If color is not failure, then return color.
101-
document().page().client().page_did_change_theme_color(color);
102-
return;
103-
}
104-
10576
update_metadata();
10677

10778
// https://html.spec.whatwg.org/multipage/semantics.html#pragma-directives

0 commit comments

Comments
 (0)