LibWeb+LibWebView+WebContent: Add support for meta theme-color

This commit is contained in:
Junior Rantila 2023-09-19 01:51:48 +02:00 committed by Andrew Kaster
parent 3c27843cfe
commit a5b01689f1
8 changed files with 61 additions and 0 deletions

View file

@ -6,8 +6,14 @@
*/
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/CSS/Parser/ParsingContext.h>
#include <LibWeb/CSS/PropertyID.h>
#include <LibWeb/CSS/StyleValues/ColorStyleValue.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/HTMLMetaElement.h>
#include <LibWeb/Infra/CharacterTypes.h>
#include <LibWeb/Page/Page.h>
namespace Web::HTML {
@ -41,6 +47,43 @@ void HTMLMetaElement::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 name = attribute(AttributeNames::name);
auto content = attribute(AttributeNames::content);
if (name.has_value() && name->bytes_as_string_view().equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) {
auto* page = document().page();
if (!page)
return;
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 (!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->as_color().color();
// 4. If color is not failure, then return color.
page->client().page_did_change_theme_color(color);
return;
}
// 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
// the above states, then the user agent must run the algorithm appropriate for that state, as described in the

View file

@ -256,6 +256,8 @@ public:
virtual void page_did_finish_text_test() {};
virtual void page_did_change_theme_color(Gfx::Color) { }
protected:
virtual ~PageClient() = default;
};

View file

@ -154,6 +154,7 @@ public:
Function<void(Color current_color)> on_request_color_picker;
Function<void(bool)> on_finish_handling_input_event;
Function<void()> on_text_test_finish;
Function<void(Gfx::Color)> on_theme_color_change;
virtual Gfx::IntRect viewport_rect() const = 0;
virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const = 0;

View file

@ -396,4 +396,10 @@ void WebContentClient::did_finish_handling_input_event(bool event_was_accepted)
m_view.on_finish_handling_input_event(event_was_accepted);
}
void WebContentClient::did_change_theme_color(Gfx::Color color)
{
if (m_view.on_theme_color_change)
m_view.on_theme_color_change(color);
}
}

View file

@ -85,6 +85,7 @@ private:
virtual void did_request_color_picker(Color const& current_color) override;
virtual void did_finish_handling_input_event(bool event_was_accepted) override;
virtual void did_finish_text_test() override;
virtual void did_change_theme_color(Gfx::Color color) override;
ViewImplementation& m_view;
};

View file

@ -463,4 +463,9 @@ void PageHost::page_did_request_color_picker(Color current_color)
m_client.async_did_request_color_picker(current_color);
}
void PageHost::page_did_change_theme_color(Gfx::Color color)
{
m_client.async_did_change_theme_color(color);
}
}

View file

@ -116,6 +116,7 @@ private:
virtual void request_file(Web::FileRequest) override;
virtual void page_did_request_color_picker(Color current_color) override;
virtual void page_did_finish_text_test() override;
virtual void page_did_change_theme_color(Gfx::Color color) override;
explicit PageHost(ConnectionFromClient&);

View file

@ -1,5 +1,6 @@
#include <AK/URL.h>
#include <LibCore/AnonymousBuffer.h>
#include <LibGfx/Color.h>
#include <LibGfx/ShareableBitmap.h>
#include <LibWeb/Cookie/Cookie.h>
#include <LibWeb/Cookie/ParsedCookie.h>
@ -61,6 +62,7 @@ endpoint WebContentClient
did_request_file(DeprecatedString path, i32 request_id) =|
did_request_color_picker(Color current_color) =|
did_finish_handling_input_event(bool event_was_accepted) =|
did_change_theme_color(Gfx::Color color) =|
did_output_js_console_message(i32 message_index) =|
did_get_js_console_messages(i32 start_index, Vector<DeprecatedString> message_types, Vector<DeprecatedString> messages) =|