mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-08 01:00:05 +00:00
LibWeb: Obtain theme-color on meta element removal and modification
This commit is contained in:
parent
df70455d3f
commit
4a0ac312cc
Notes:
github-actions[bot]
2025-01-08 11:19:28 +00:00
Author: https://github.com/Gingeh
Commit: 4a0ac312cc
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3146
Reviewed-by: https://github.com/AtkinsSJ ✅
3 changed files with 55 additions and 35 deletions
|
@ -1471,6 +1471,53 @@ void Document::obtain_supported_color_schemes()
|
||||||
// 3. Return null.
|
// 3. Return null.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/semantics.html#meta-theme-color
|
||||||
|
void Document::obtain_theme_color()
|
||||||
|
{
|
||||||
|
Color theme_color = Color::Transparent;
|
||||||
|
|
||||||
|
// 1. Let candidate elements be the list of all meta elements that meet the following criteria, in tree order:
|
||||||
|
for_each_in_subtree_of_type<HTML::HTMLMetaElement>([&](HTML::HTMLMetaElement& element) {
|
||||||
|
// * the element is in a document tree;
|
||||||
|
// * the element has a name attribute, whose value is an ASCII case-insensitive match for theme-color; and
|
||||||
|
// * the element has a content attribute.
|
||||||
|
|
||||||
|
// 2. For each element in candidate elements:
|
||||||
|
auto content = element.attribute(HTML::AttributeNames::content);
|
||||||
|
if (element.name().has_value() && element.name()->equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) {
|
||||||
|
// 1. If element has a media attribute and the value of element's media attribute does not match the environment, then continue.
|
||||||
|
auto context = CSS::Parser::ParsingContext { document() };
|
||||||
|
auto media = element.attribute(HTML::AttributeNames::media);
|
||||||
|
if (media.has_value()) {
|
||||||
|
auto query = parse_media_query(context, media.value());
|
||||||
|
if (window() && !query->evaluate(*window()))
|
||||||
|
return TraversalDecision::Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Let value be the result of stripping leading and trailing ASCII whitespace from the value of element's content attribute.
|
||||||
|
auto value = content->bytes_as_string_view().trim(Infra::ASCII_WHITESPACE);
|
||||||
|
|
||||||
|
// 3. Let color be the result of parsing value.
|
||||||
|
auto css_value = parse_css_value(context, value, CSS::PropertyID::Color);
|
||||||
|
|
||||||
|
// 4. If color is not failure, then return color.
|
||||||
|
if (!css_value.is_null() && css_value->is_color()) {
|
||||||
|
Optional<Layout::NodeWithStyle const&> root_node;
|
||||||
|
if (html_element())
|
||||||
|
root_node = *html_element()->layout_node();
|
||||||
|
|
||||||
|
theme_color = css_value->to_color(root_node);
|
||||||
|
return TraversalDecision::Break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TraversalDecision::Continue;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Return nothing(the page has no theme color).
|
||||||
|
document().page().client().page_did_change_theme_color(theme_color);
|
||||||
|
}
|
||||||
|
|
||||||
Layout::Viewport const* Document::layout_node() const
|
Layout::Viewport const* Document::layout_node() const
|
||||||
{
|
{
|
||||||
return static_cast<Layout::Viewport const*>(Node::layout_node());
|
return static_cast<Layout::Viewport const*>(Node::layout_node());
|
||||||
|
|
|
@ -245,6 +245,8 @@ public:
|
||||||
Optional<Vector<String> const&> supported_color_schemes() const;
|
Optional<Vector<String> const&> supported_color_schemes() const;
|
||||||
void obtain_supported_color_schemes();
|
void obtain_supported_color_schemes();
|
||||||
|
|
||||||
|
void obtain_theme_color();
|
||||||
|
|
||||||
void update_style();
|
void update_style();
|
||||||
void update_layout();
|
void update_layout();
|
||||||
void update_paint_and_hit_testing_properties_if_needed();
|
void update_paint_and_hit_testing_properties_if_needed();
|
||||||
|
|
|
@ -51,14 +51,18 @@ Optional<HTMLMetaElement::HttpEquivAttributeState> HTMLMetaElement::http_equiv_s
|
||||||
void HTMLMetaElement::update_metadata(Optional<String> const& old_name)
|
void HTMLMetaElement::update_metadata(Optional<String> const& old_name)
|
||||||
{
|
{
|
||||||
if (name().has_value()) {
|
if (name().has_value()) {
|
||||||
if (name()->equals_ignoring_ascii_case("color-scheme"sv)) {
|
if (name()->equals_ignoring_ascii_case("theme-color"sv)) {
|
||||||
|
document().obtain_theme_color();
|
||||||
|
} else if (name()->equals_ignoring_ascii_case("color-scheme"sv)) {
|
||||||
document().obtain_supported_color_schemes();
|
document().obtain_supported_color_schemes();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_name.has_value()) {
|
if (old_name.has_value()) {
|
||||||
if (old_name->equals_ignoring_ascii_case("color-scheme"sv)) {
|
if (old_name->equals_ignoring_ascii_case("theme-color"sv)) {
|
||||||
|
document().obtain_theme_color();
|
||||||
|
} else if (old_name->equals_ignoring_ascii_case("color-scheme"sv)) {
|
||||||
document().obtain_supported_color_schemes();
|
document().obtain_supported_color_schemes();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -69,39 +73,6 @@ void HTMLMetaElement::inserted()
|
||||||
{
|
{
|
||||||
Base::inserted();
|
Base::inserted();
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/semantics.html#meta-theme-color
|
|
||||||
// 1. To obtain a page's theme color, user agents must run the following steps:
|
|
||||||
// * The element is in a document tree
|
|
||||||
// * The element has a name attribute, whose value is an ASCII case-insensitive match for theme-color
|
|
||||||
// * The element has a content attribute
|
|
||||||
auto content = attribute(AttributeNames::content);
|
|
||||||
if (name().has_value() && name()->equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) {
|
|
||||||
auto context = CSS::Parser::ParsingContext { document() };
|
|
||||||
|
|
||||||
// 2. For each element in candidate elements:
|
|
||||||
|
|
||||||
// 1. If element has a media attribute and the value of element's media attribute does not match the environment, then continue.
|
|
||||||
auto media = attribute(AttributeNames::media);
|
|
||||||
if (media.has_value()) {
|
|
||||||
auto query = parse_media_query(context, media.value());
|
|
||||||
if (document().window() && !query->evaluate(*document().window()))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Let value be the result of stripping leading and trailing ASCII whitespace from the value of element's content attribute.
|
|
||||||
auto value = content->bytes_as_string_view().trim(Infra::ASCII_WHITESPACE);
|
|
||||||
|
|
||||||
// 3. Let color be the result of parsing value.
|
|
||||||
auto css_value = parse_css_value(context, value, CSS::PropertyID::Color);
|
|
||||||
if (css_value.is_null() || !css_value->is_color())
|
|
||||||
return;
|
|
||||||
auto color = css_value->to_color({}); // TODO: Pass a layout node?
|
|
||||||
|
|
||||||
// 4. If color is not failure, then return color.
|
|
||||||
document().page().client().page_did_change_theme_color(color);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_metadata();
|
update_metadata();
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/semantics.html#pragma-directives
|
// https://html.spec.whatwg.org/multipage/semantics.html#pragma-directives
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue