Prechádzať zdrojové kódy

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

Junior Rantila 1 rok pred
rodič
commit
a5b01689f1

+ 43 - 0
Userland/Libraries/LibWeb/HTML/HTMLMetaElement.cpp

@@ -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

+ 2 - 0
Userland/Libraries/LibWeb/Page/Page.h

@@ -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;
 };

+ 1 - 0
Userland/Libraries/LibWebView/ViewImplementation.h

@@ -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;

+ 6 - 0
Userland/Libraries/LibWebView/WebContentClient.cpp

@@ -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);
+}
+
 }

+ 1 - 0
Userland/Libraries/LibWebView/WebContentClient.h

@@ -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;
 };

+ 5 - 0
Userland/Services/WebContent/PageHost.cpp

@@ -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);
+}
+
 }

+ 1 - 0
Userland/Services/WebContent/PageHost.h

@@ -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&);
 

+ 2 - 0
Userland/Services/WebContent/WebContentClient.ipc

@@ -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) =|