mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-05 23:59:49 +00:00
LibWeb: Implement the color-scheme meta tag name
This commit is contained in:
parent
ce5cd012b9
commit
df70455d3f
Notes:
github-actions[bot]
2025-01-08 11:19:34 +00:00
Author: https://github.com/Gingeh
Commit: df70455d3f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3146
Reviewed-by: https://github.com/AtkinsSJ ✅
7 changed files with 97 additions and 3 deletions
|
@ -230,7 +230,7 @@ Color ComputedProperties::color_or_fallback(CSS::PropertyID id, Layout::NodeWith
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-color-adjust-1/#determine-the-used-color-scheme
|
// https://drafts.csswg.org/css-color-adjust-1/#determine-the-used-color-scheme
|
||||||
CSS::PreferredColorScheme ComputedProperties::color_scheme(CSS::PreferredColorScheme preferred_scheme) const
|
CSS::PreferredColorScheme ComputedProperties::color_scheme(CSS::PreferredColorScheme preferred_scheme, Optional<Vector<String> const&> document_supported_schemes) const
|
||||||
{
|
{
|
||||||
// To determine the used color scheme of an element:
|
// To determine the used color scheme of an element:
|
||||||
auto const& scheme_value = property(CSS::PropertyID::ColorScheme).as_color_scheme();
|
auto const& scheme_value = property(CSS::PropertyID::ColorScheme).as_color_scheme();
|
||||||
|
@ -254,6 +254,16 @@ CSS::PreferredColorScheme ComputedProperties::color_scheme(CSS::PreferredColorSc
|
||||||
return preferred_color_scheme_from_string(first_supported.value());
|
return preferred_color_scheme_from_string(first_supported.value());
|
||||||
|
|
||||||
// 4. Otherwise, the used color scheme is the browser default. (Same as normal.)
|
// 4. Otherwise, the used color scheme is the browser default. (Same as normal.)
|
||||||
|
// `normal` indicates that the element supports the page’s supported color schemes, if they are set
|
||||||
|
if (document_supported_schemes.has_value()) {
|
||||||
|
if (preferred_scheme != CSS::PreferredColorScheme::Auto && document_supported_schemes->contains_slow(preferred_color_scheme_to_string(preferred_scheme)))
|
||||||
|
return preferred_scheme;
|
||||||
|
|
||||||
|
auto document_first_supported = document_supported_schemes->first_matching([](auto scheme) { return preferred_color_scheme_from_string(scheme) != CSS::PreferredColorScheme::Auto; });
|
||||||
|
if (document_first_supported.has_value())
|
||||||
|
return preferred_color_scheme_from_string(document_first_supported.value());
|
||||||
|
}
|
||||||
|
|
||||||
return CSS::PreferredColorScheme::Light;
|
return CSS::PreferredColorScheme::Light;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
Optional<LengthPercentage> length_percentage(CSS::PropertyID) const;
|
Optional<LengthPercentage> length_percentage(CSS::PropertyID) const;
|
||||||
LengthBox length_box(CSS::PropertyID left_id, CSS::PropertyID top_id, CSS::PropertyID right_id, CSS::PropertyID bottom_id, const CSS::Length& default_value) const;
|
LengthBox length_box(CSS::PropertyID left_id, CSS::PropertyID top_id, CSS::PropertyID right_id, CSS::PropertyID bottom_id, const CSS::Length& default_value) const;
|
||||||
Color color_or_fallback(CSS::PropertyID, Layout::NodeWithStyle const&, Color fallback) const;
|
Color color_or_fallback(CSS::PropertyID, Layout::NodeWithStyle const&, Color fallback) const;
|
||||||
CSS::PreferredColorScheme color_scheme(CSS::PreferredColorScheme) const;
|
CSS::PreferredColorScheme color_scheme(CSS::PreferredColorScheme, Optional<Vector<String> const&> document_supported_schemes) const;
|
||||||
Optional<CSS::TextAnchor> text_anchor() const;
|
Optional<CSS::TextAnchor> text_anchor() const;
|
||||||
Optional<CSS::TextAlign> text_align() const;
|
Optional<CSS::TextAlign> text_align() const;
|
||||||
Optional<CSS::TextJustify> text_justify() const;
|
Optional<CSS::TextJustify> text_justify() const;
|
||||||
|
|
|
@ -37,9 +37,11 @@
|
||||||
#include <LibWeb/CSS/FontFaceSet.h>
|
#include <LibWeb/CSS/FontFaceSet.h>
|
||||||
#include <LibWeb/CSS/MediaQueryList.h>
|
#include <LibWeb/CSS/MediaQueryList.h>
|
||||||
#include <LibWeb/CSS/MediaQueryListEvent.h>
|
#include <LibWeb/CSS/MediaQueryListEvent.h>
|
||||||
|
#include <LibWeb/CSS/Parser/Parser.h>
|
||||||
#include <LibWeb/CSS/SelectorEngine.h>
|
#include <LibWeb/CSS/SelectorEngine.h>
|
||||||
#include <LibWeb/CSS/StyleComputer.h>
|
#include <LibWeb/CSS/StyleComputer.h>
|
||||||
#include <LibWeb/CSS/StyleSheetIdentifier.h>
|
#include <LibWeb/CSS/StyleSheetIdentifier.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/ColorSchemeStyleValue.h>
|
||||||
#include <LibWeb/CSS/SystemColor.h>
|
#include <LibWeb/CSS/SystemColor.h>
|
||||||
#include <LibWeb/CSS/TransitionEvent.h>
|
#include <LibWeb/CSS/TransitionEvent.h>
|
||||||
#include <LibWeb/CSS/VisualViewport.h>
|
#include <LibWeb/CSS/VisualViewport.h>
|
||||||
|
@ -98,6 +100,7 @@
|
||||||
#include <LibWeb/HTML/HTMLImageElement.h>
|
#include <LibWeb/HTML/HTMLImageElement.h>
|
||||||
#include <LibWeb/HTML/HTMLInputElement.h>
|
#include <LibWeb/HTML/HTMLInputElement.h>
|
||||||
#include <LibWeb/HTML/HTMLLinkElement.h>
|
#include <LibWeb/HTML/HTMLLinkElement.h>
|
||||||
|
#include <LibWeb/HTML/HTMLMetaElement.h>
|
||||||
#include <LibWeb/HTML/HTMLObjectElement.h>
|
#include <LibWeb/HTML/HTMLObjectElement.h>
|
||||||
#include <LibWeb/HTML/HTMLScriptElement.h>
|
#include <LibWeb/HTML/HTMLScriptElement.h>
|
||||||
#include <LibWeb/HTML/HTMLStyleElement.h>
|
#include <LibWeb/HTML/HTMLStyleElement.h>
|
||||||
|
@ -1432,6 +1435,42 @@ void Document::set_visited_link_color(Color color)
|
||||||
m_visited_link_color = color;
|
m_visited_link_color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<Vector<String> const&> Document::supported_color_schemes() const
|
||||||
|
{
|
||||||
|
return m_supported_color_schemes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/semantics.html#meta-color-scheme
|
||||||
|
void Document::obtain_supported_color_schemes()
|
||||||
|
{
|
||||||
|
m_supported_color_schemes = {};
|
||||||
|
|
||||||
|
// 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 color-scheme; 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("color-scheme"sv) && content.has_value()) {
|
||||||
|
// 1. Let parsed be the result of parsing a list of component values given the value of element's content attribute.
|
||||||
|
auto context = CSS::Parser::ParsingContext { document() };
|
||||||
|
auto parsed = parse_css_value(context, content.value(), CSS::PropertyID::ColorScheme);
|
||||||
|
|
||||||
|
// 2. If parsed is a valid CSS 'color-scheme' property value, then return parsed.
|
||||||
|
if (!parsed.is_null() && parsed->is_color_scheme()) {
|
||||||
|
m_supported_color_schemes = parsed->as_color_scheme().schemes();
|
||||||
|
return TraversalDecision::Break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TraversalDecision::Continue;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Return null.
|
||||||
|
}
|
||||||
|
|
||||||
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());
|
||||||
|
|
|
@ -242,6 +242,9 @@ public:
|
||||||
Optional<Color> visited_link_color() const;
|
Optional<Color> visited_link_color() const;
|
||||||
void set_visited_link_color(Color);
|
void set_visited_link_color(Color);
|
||||||
|
|
||||||
|
Optional<Vector<String> const&> supported_color_schemes() const;
|
||||||
|
void obtain_supported_color_schemes();
|
||||||
|
|
||||||
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();
|
||||||
|
@ -829,6 +832,8 @@ private:
|
||||||
Optional<Color> m_active_link_color;
|
Optional<Color> m_active_link_color;
|
||||||
Optional<Color> m_visited_link_color;
|
Optional<Color> m_visited_link_color;
|
||||||
|
|
||||||
|
Optional<Vector<String>> m_supported_color_schemes;
|
||||||
|
|
||||||
GC::Ptr<HTML::HTMLParser> m_parser;
|
GC::Ptr<HTML::HTMLParser> m_parser;
|
||||||
bool m_active_parser_was_aborted { false };
|
bool m_active_parser_was_aborted { false };
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <LibWeb/CSS/Parser/ParsingContext.h>
|
#include <LibWeb/CSS/Parser/ParsingContext.h>
|
||||||
#include <LibWeb/CSS/PropertyID.h>
|
#include <LibWeb/CSS/PropertyID.h>
|
||||||
#include <LibWeb/CSS/StyleValues/CSSColorValue.h>
|
#include <LibWeb/CSS/StyleValues/CSSColorValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/ColorSchemeStyleValue.h>
|
||||||
#include <LibWeb/DOM/Document.h>
|
#include <LibWeb/DOM/Document.h>
|
||||||
#include <LibWeb/HTML/HTMLMetaElement.h>
|
#include <LibWeb/HTML/HTMLMetaElement.h>
|
||||||
#include <LibWeb/Infra/CharacterTypes.h>
|
#include <LibWeb/Infra/CharacterTypes.h>
|
||||||
|
@ -47,6 +48,23 @@ Optional<HTMLMetaElement::HttpEquivAttributeState> HTMLMetaElement::http_equiv_s
|
||||||
return OptionalNone {};
|
return OptionalNone {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTMLMetaElement::update_metadata(Optional<String> const& old_name)
|
||||||
|
{
|
||||||
|
if (name().has_value()) {
|
||||||
|
if (name()->equals_ignoring_ascii_case("color-scheme"sv)) {
|
||||||
|
document().obtain_supported_color_schemes();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_name.has_value()) {
|
||||||
|
if (old_name->equals_ignoring_ascii_case("color-scheme"sv)) {
|
||||||
|
document().obtain_supported_color_schemes();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HTMLMetaElement::inserted()
|
void HTMLMetaElement::inserted()
|
||||||
{
|
{
|
||||||
Base::inserted();
|
Base::inserted();
|
||||||
|
@ -84,6 +102,8 @@ void HTMLMetaElement::inserted()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_metadata();
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/semantics.html#pragma-directives
|
// https://html.spec.whatwg.org/multipage/semantics.html#pragma-directives
|
||||||
// When a meta element is inserted into the document, if its http-equiv attribute is present and represents one of
|
// When a meta element is inserted into the document, if its http-equiv attribute is present and represents one of
|
||||||
// the above states, then the user agent must run the algorithm appropriate for that state, as described in the
|
// the above states, then the user agent must run the algorithm appropriate for that state, as described in the
|
||||||
|
@ -160,4 +180,20 @@ void HTMLMetaElement::inserted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTMLMetaElement::removed_from(Node* parent)
|
||||||
|
{
|
||||||
|
Base::removed_from(parent);
|
||||||
|
update_metadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HTMLMetaElement::attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_)
|
||||||
|
{
|
||||||
|
Base::attribute_changed(local_name, old_value, value, namespace_);
|
||||||
|
if (local_name == HTML::AttributeNames::name) {
|
||||||
|
update_metadata(old_value);
|
||||||
|
} else {
|
||||||
|
update_metadata();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,12 @@ private:
|
||||||
|
|
||||||
virtual void initialize(JS::Realm&) override;
|
virtual void initialize(JS::Realm&) override;
|
||||||
|
|
||||||
|
void update_metadata(Optional<String> const& old_name = {});
|
||||||
|
|
||||||
// ^DOM::Element
|
// ^DOM::Element
|
||||||
virtual void inserted() override;
|
virtual void inserted() override;
|
||||||
|
virtual void removed_from(Node*) override;
|
||||||
|
virtual void attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -334,7 +334,7 @@ void NodeWithStyle::apply_style(const CSS::ComputedProperties& computed_style)
|
||||||
if (preferred_color_scheme != CSS::PreferredColorScheme::Dark && preferred_color_scheme != CSS::PreferredColorScheme::Light) {
|
if (preferred_color_scheme != CSS::PreferredColorScheme::Dark && preferred_color_scheme != CSS::PreferredColorScheme::Light) {
|
||||||
preferred_color_scheme = document().page().palette().is_dark() ? CSS::PreferredColorScheme::Dark : CSS::PreferredColorScheme::Light;
|
preferred_color_scheme = document().page().palette().is_dark() ? CSS::PreferredColorScheme::Dark : CSS::PreferredColorScheme::Light;
|
||||||
}
|
}
|
||||||
computed_values.set_color_scheme(computed_style.color_scheme(preferred_color_scheme));
|
computed_values.set_color_scheme(computed_style.color_scheme(preferred_color_scheme, document().supported_color_schemes()));
|
||||||
|
|
||||||
// NOTE: color must be set second to ensure currentColor can be resolved in other properties (e.g. background-color).
|
// NOTE: color must be set second to ensure currentColor can be resolved in other properties (e.g. background-color).
|
||||||
computed_values.set_color(computed_style.color_or_fallback(CSS::PropertyID::Color, *this, CSS::InitialValues::color()));
|
computed_values.set_color(computed_style.color_or_fallback(CSS::PropertyID::Color, *this, CSS::InitialValues::color()));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue