mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 11:12:45 +00:00 
			
		
		
		
	LibWeb+LibWebView+WebContent: Add support for meta theme-color
This commit is contained in:
		
							parent
							
								
									3c27843cfe
								
							
						
					
					
						commit
						a5b01689f1
					
				
					 8 changed files with 61 additions and 0 deletions
				
			
		|  | @ -6,8 +6,14 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <LibWeb/Bindings/Intrinsics.h> | #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/DOM/Document.h> | ||||||
| #include <LibWeb/HTML/HTMLMetaElement.h> | #include <LibWeb/HTML/HTMLMetaElement.h> | ||||||
|  | #include <LibWeb/Infra/CharacterTypes.h> | ||||||
|  | #include <LibWeb/Page/Page.h> | ||||||
| 
 | 
 | ||||||
| namespace Web::HTML { | namespace Web::HTML { | ||||||
| 
 | 
 | ||||||
|  | @ -41,6 +47,43 @@ 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 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
 |     // 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
 | ||||||
|  |  | ||||||
|  | @ -256,6 +256,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     virtual void page_did_finish_text_test() {}; |     virtual void page_did_finish_text_test() {}; | ||||||
| 
 | 
 | ||||||
|  |     virtual void page_did_change_theme_color(Gfx::Color) { } | ||||||
|  | 
 | ||||||
| protected: | protected: | ||||||
|     virtual ~PageClient() = default; |     virtual ~PageClient() = default; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -154,6 +154,7 @@ public: | ||||||
|     Function<void(Color current_color)> on_request_color_picker; |     Function<void(Color current_color)> on_request_color_picker; | ||||||
|     Function<void(bool)> on_finish_handling_input_event; |     Function<void(bool)> on_finish_handling_input_event; | ||||||
|     Function<void()> on_text_test_finish; |     Function<void()> on_text_test_finish; | ||||||
|  |     Function<void(Gfx::Color)> on_theme_color_change; | ||||||
| 
 | 
 | ||||||
|     virtual Gfx::IntRect viewport_rect() const = 0; |     virtual Gfx::IntRect viewport_rect() const = 0; | ||||||
|     virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const = 0; |     virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const = 0; | ||||||
|  |  | ||||||
|  | @ -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); |         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); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -85,6 +85,7 @@ private: | ||||||
|     virtual void did_request_color_picker(Color const& current_color) override; |     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_handling_input_event(bool event_was_accepted) override; | ||||||
|     virtual void did_finish_text_test() override; |     virtual void did_finish_text_test() override; | ||||||
|  |     virtual void did_change_theme_color(Gfx::Color color) override; | ||||||
| 
 | 
 | ||||||
|     ViewImplementation& m_view; |     ViewImplementation& m_view; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -463,4 +463,9 @@ void PageHost::page_did_request_color_picker(Color current_color) | ||||||
|     m_client.async_did_request_color_picker(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); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -116,6 +116,7 @@ private: | ||||||
|     virtual void request_file(Web::FileRequest) override; |     virtual void request_file(Web::FileRequest) override; | ||||||
|     virtual void page_did_request_color_picker(Color current_color) override; |     virtual void page_did_request_color_picker(Color current_color) override; | ||||||
|     virtual void page_did_finish_text_test() override; |     virtual void page_did_finish_text_test() override; | ||||||
|  |     virtual void page_did_change_theme_color(Gfx::Color color) override; | ||||||
| 
 | 
 | ||||||
|     explicit PageHost(ConnectionFromClient&); |     explicit PageHost(ConnectionFromClient&); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #include <AK/URL.h> | #include <AK/URL.h> | ||||||
| #include <LibCore/AnonymousBuffer.h> | #include <LibCore/AnonymousBuffer.h> | ||||||
|  | #include <LibGfx/Color.h> | ||||||
| #include <LibGfx/ShareableBitmap.h> | #include <LibGfx/ShareableBitmap.h> | ||||||
| #include <LibWeb/Cookie/Cookie.h> | #include <LibWeb/Cookie/Cookie.h> | ||||||
| #include <LibWeb/Cookie/ParsedCookie.h> | #include <LibWeb/Cookie/ParsedCookie.h> | ||||||
|  | @ -61,6 +62,7 @@ endpoint WebContentClient | ||||||
|     did_request_file(DeprecatedString path, i32 request_id) =| |     did_request_file(DeprecatedString path, i32 request_id) =| | ||||||
|     did_request_color_picker(Color current_color) =| |     did_request_color_picker(Color current_color) =| | ||||||
|     did_finish_handling_input_event(bool event_was_accepted) =| |     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_output_js_console_message(i32 message_index) =| | ||||||
|     did_get_js_console_messages(i32 start_index, Vector<DeprecatedString> message_types, Vector<DeprecatedString> messages) =| |     did_get_js_console_messages(i32 start_index, Vector<DeprecatedString> message_types, Vector<DeprecatedString> messages) =| | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Junior Rantila
						Junior Rantila