Title: [276333] trunk
Revision
276333
Author
[email protected]
Date
2021-04-20 17:14:59 -0700 (Tue, 20 Apr 2021)

Log Message

Parse `theme_color` in web application manifests and pass it along to `-[WKWebView themeColor]`
https://bugs.webkit.org/show_bug.cgi?id=224796

Reviewed by Darin Adler.

Source/WebCore:

* Modules/applicationmanifest/ApplicationManifest.h:
(WebCore::ApplicationManifest::encode const):
(WebCore::ApplicationManifest::decode):

* Modules/applicationmanifest/ApplicationManifestParser.h:
* Modules/applicationmanifest/ApplicationManifestParser.cpp:
(WebCore::ApplicationManifestParser::parse):
(WebCore::ApplicationManifestParser::ApplicationManifestParser):
(WebCore::ApplicationManifestParser::parseManifest):
(WebCore::ApplicationManifestParser::logDeveloperWarning):
(WebCore::ApplicationManifestParser::parseColor): Added.
* loader/cache/CachedApplicationManifest.h:
* loader/cache/CachedApplicationManifest.cpp:
(WebCore::CachedApplicationManifest::process):
Pass an actual `Document` instead of a `ScriptExecutionContext` so that we can notify it
when finished parsing the JSON (`Document::processApplicationManifest`).

* dom/Document.h:
(WebCore::Document::themeColor const):
* dom/Document.cpp:
(WebCore::Document::processMetaElementThemeColor): Added.
(WebCore::Document::themeColorChanged): Added.
(WebCore::Document::processApplicationManifest): Added.
(WebCore::Document::processThemeColor): Deleted.
Use the theme color from `<meta name="theme-color">` if valid, falling back to the theme
color from `"theme_color"` in the web application manifest (if specified). Only notify the
UIProcess of changes to `<meta name="theme-color">` or the `"theme_color"` in the web
application manifest if the new value is the value that would be used.

* html/HTMLMetaElement.cpp:
(WebCore::HTMLMetaElement::attributeChanged):
(WebCore::HTMLMetaElement::removedFromAncestor):
(WebCore::HTMLMetaElement::process):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::rootBackgroundColorOrTransparencyChanged):
Drive-by: Rename `Document::processThemeColor` to `Document::processMetaElementThemeColor`
so that it's more specific to `<meta name="theme-color">`.

* page/ChromeClient.h:
(WebCore::ChromeClient::themeColorChanged const):
(WebCore::ChromeClient::pageExtendedBackgroundColorDidChange const):
Drive-by: Remove the `Color` parameter since it's not actually used in the WebProcess.

Source/WebKit:

* UIProcess/API/Cocoa/_WKApplicationManifest.h:
* UIProcess/API/Cocoa/_WKApplicationManifest.mm:
(-[_WKApplicationManifest initWithCoder:]):
(-[_WKApplicationManifest encodeWithCoder:]):
(-[_WKApplicationManifest themeColor]): Added.

* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::themeColorChanged const):
(WebKit::WebChromeClient::pageExtendedBackgroundColorDidChange const):
Drive-by: Remove the `Color` parameter since it's not actually used in the WebProcess.

Tools:

* TestWebKitAPI/Tests/WebCore/ApplicationManifestParser.cpp:
(ApplicationManifestParserTest::testThemeColor): Added.
(TEST_F.ApplicationManifestParserTest.ThemeColor): Added.

* TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm:
(TEST.ApplicationManifestBasic):
(TEST.ApplicationManifestCoding):

* TestWebKitAPI/Tests/WebKitCocoa/WKWebViewThemeColor.mm: Renamed from Tools/TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm.
(TEST.WKWebViewThemeColor.ApplicationManifest):
(TEST.WKWebViewThemeColor.MetaElementOverridesApplicationManifest):
Rename this file now that it also deals with web application manifest (in addition to `<meta name="theme-color">`).

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (276332 => 276333)


--- trunk/Source/WebCore/ChangeLog	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/ChangeLog	2021-04-21 00:14:59 UTC (rev 276333)
@@ -1,3 +1,53 @@
+2021-04-20  Devin Rousso  <[email protected]>
+
+        Parse `theme_color` in web application manifests and pass it along to `-[WKWebView themeColor]`
+        https://bugs.webkit.org/show_bug.cgi?id=224796
+
+        Reviewed by Darin Adler.
+
+        * Modules/applicationmanifest/ApplicationManifest.h:
+        (WebCore::ApplicationManifest::encode const):
+        (WebCore::ApplicationManifest::decode):
+
+        * Modules/applicationmanifest/ApplicationManifestParser.h:
+        * Modules/applicationmanifest/ApplicationManifestParser.cpp:
+        (WebCore::ApplicationManifestParser::parse):
+        (WebCore::ApplicationManifestParser::ApplicationManifestParser):
+        (WebCore::ApplicationManifestParser::parseManifest):
+        (WebCore::ApplicationManifestParser::logDeveloperWarning):
+        (WebCore::ApplicationManifestParser::parseColor): Added.
+        * loader/cache/CachedApplicationManifest.h:
+        * loader/cache/CachedApplicationManifest.cpp:
+        (WebCore::CachedApplicationManifest::process):
+        Pass an actual `Document` instead of a `ScriptExecutionContext` so that we can notify it
+        when finished parsing the JSON (`Document::processApplicationManifest`).
+
+        * dom/Document.h:
+        (WebCore::Document::themeColor const):
+        * dom/Document.cpp:
+        (WebCore::Document::processMetaElementThemeColor): Added.
+        (WebCore::Document::themeColorChanged): Added.
+        (WebCore::Document::processApplicationManifest): Added.
+        (WebCore::Document::processThemeColor): Deleted.
+        Use the theme color from `<meta name="theme-color">` if valid, falling back to the theme
+        color from `"theme_color"` in the web application manifest (if specified). Only notify the
+        UIProcess of changes to `<meta name="theme-color">` or the `"theme_color"` in the web
+        application manifest if the new value is the value that would be used.
+
+        * html/HTMLMetaElement.cpp:
+        (WebCore::HTMLMetaElement::attributeChanged):
+        (WebCore::HTMLMetaElement::removedFromAncestor):
+        (WebCore::HTMLMetaElement::process):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::rootBackgroundColorOrTransparencyChanged):
+        Drive-by: Rename `Document::processThemeColor` to `Document::processMetaElementThemeColor`
+        so that it's more specific to `<meta name="theme-color">`.
+
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::themeColorChanged const):
+        (WebCore::ChromeClient::pageExtendedBackgroundColorDidChange const):
+        Drive-by: Remove the `Color` parameter since it's not actually used in the WebProcess.
+
 2021-04-20  Michael Catanzaro  <[email protected]>
 
         Lots of spurious -Wnonnull warnings with GCC 11

Modified: trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h (276332 => 276333)


--- trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h	2021-04-21 00:14:59 UTC (rev 276333)
@@ -27,6 +27,7 @@
 
 #if ENABLE(APPLICATION_MANIFEST)
 
+#include "Color.h"
 #include <wtf/EnumTraits.h>
 #include <wtf/Optional.h>
 #include <wtf/URL.h>
@@ -47,6 +48,7 @@
     URL scope;
     Display display;
     URL startURL;
+    Color themeColor;
 
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static Optional<ApplicationManifest> decode(Decoder&);
@@ -55,7 +57,7 @@
 template<class Encoder>
 void ApplicationManifest::encode(Encoder& encoder) const
 {
-    encoder << name << shortName << description << scope << display << startURL;
+    encoder << name << shortName << description << scope << display << startURL << themeColor;
 }
 
 template<class Decoder>
@@ -75,6 +77,8 @@
         return WTF::nullopt;
     if (!decoder.decode(result.startURL))
         return WTF::nullopt;
+    if (!decoder.decode(result.themeColor))
+        return WTF::nullopt;
 
     return result;
 }

Modified: trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.cpp (276332 => 276333)


--- trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.cpp	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.cpp	2021-04-21 00:14:59 UTC (rev 276333)
@@ -28,14 +28,17 @@
 
 #if ENABLE(APPLICATION_MANIFEST)
 
+#include "CSSParser.h"
+#include "Color.h"
+#include "Document.h"
 #include "SecurityOrigin.h"
 #include <_javascript_Core/ConsoleMessage.h>
 
 namespace WebCore {
 
-ApplicationManifest ApplicationManifestParser::parse(ScriptExecutionContext& scriptExecutionContext, const String& source, const URL& manifestURL, const URL& documentURL)
+ApplicationManifest ApplicationManifestParser::parse(Document& document, const String& source, const URL& manifestURL, const URL& documentURL)
 {
-    ApplicationManifestParser parser { &scriptExecutionContext };
+    ApplicationManifestParser parser { &document };
     return parser.parseManifest(source, manifestURL, documentURL);
 }
 
@@ -45,8 +48,8 @@
     return parser.parseManifest(source, manifestURL, documentURL);
 }
 
-ApplicationManifestParser::ApplicationManifestParser(RefPtr<ScriptExecutionContext> consoleContext)
-    : m_consoleContext(consoleContext)
+ApplicationManifestParser::ApplicationManifestParser(RefPtr<Document> document)
+    : m_document(document)
 {
 }
 
@@ -74,7 +77,11 @@
     parsedManifest.description = parseDescription(*manifest);
     parsedManifest.shortName = parseShortName(*manifest);
     parsedManifest.scope = parseScope(*manifest, documentURL, parsedManifest.startURL);
+    parsedManifest.themeColor = parseColor(*manifest, "theme_color"_s);
 
+    if (m_document)
+        m_document->processApplicationManifest(parsedManifest);
+
     return parsedManifest;
 }
 
@@ -90,8 +97,8 @@
 
 void ApplicationManifestParser::logDeveloperWarning(const String& message)
 {
-    if (m_consoleContext)
-        m_consoleContext->addConsoleMessage(makeUnique<Inspector::ConsoleMessage>(JSC::MessageSource::Other, JSC::MessageType::Log, JSC::MessageLevel::Warning, makeString("Parsing application manifest "_s, m_manifestURL.string(), ": "_s, message)));
+    if (m_document)
+        m_document->addConsoleMessage(makeUnique<Inspector::ConsoleMessage>(JSC::MessageSource::Other, JSC::MessageType::Log, JSC::MessageLevel::Warning, makeString("Parsing application manifest "_s, m_manifestURL.string(), ": "_s, message)));
 }
 
 URL ApplicationManifestParser::parseStartURL(const JSON::Object& manifest, const URL& documentURL)
@@ -229,6 +236,11 @@
     return scopeURL;
 }
 
+Color ApplicationManifestParser::parseColor(const JSON::Object& manifest, const String& propertyName)
+{
+    return CSSParser::parseColor(parseGenericString(manifest, propertyName));
+}
+
 String ApplicationManifestParser::parseGenericString(const JSON::Object& manifest, const String& propertyName)
 {
     auto value = manifest.getValue(propertyName);

Modified: trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.h (276332 => 276333)


--- trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.h	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.h	2021-04-21 00:14:59 UTC (rev 276333)
@@ -28,18 +28,20 @@
 #if ENABLE(APPLICATION_MANIFEST)
 
 #include "ApplicationManifest.h"
-#include "ScriptExecutionContext.h"
 #include <wtf/JSONValues.h>
 
 namespace WebCore {
 
+class Color;
+class Document;
+
 class ApplicationManifestParser {
 public:
-    WEBCORE_EXPORT static ApplicationManifest parse(ScriptExecutionContext&, const String&, const URL& manifestURL, const URL& documentURL);
+    WEBCORE_EXPORT static ApplicationManifest parse(Document&, const String&, const URL& manifestURL, const URL& documentURL);
     WEBCORE_EXPORT static ApplicationManifest parse(const String&, const URL& manifestURL, const URL& documentURL);
 
 private:
-    ApplicationManifestParser(RefPtr<ScriptExecutionContext>);
+    ApplicationManifestParser(RefPtr<Document>);
     ApplicationManifest parseManifest(const String&, const URL&, const URL&);
 
     URL parseStartURL(const JSON::Object&, const URL&);
@@ -49,6 +51,7 @@
     String parseShortName(const JSON::Object&);
     URL parseScope(const JSON::Object&, const URL&, const URL&);
 
+    Color parseColor(const JSON::Object&, const String& propertyName);
     String parseGenericString(const JSON::Object&, const String&);
 
     void logManifestPropertyNotAString(const String&);
@@ -55,7 +58,7 @@
     void logManifestPropertyInvalidURL(const String&);
     void logDeveloperWarning(const String& message);
 
-    RefPtr<ScriptExecutionContext> m_consoleContext;
+    RefPtr<Document> m_document;
     URL m_manifestURL;
 };
 

Modified: trunk/Source/WebCore/dom/Document.cpp (276332 => 276333)


--- trunk/Source/WebCore/dom/Document.cpp	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/dom/Document.cpp	2021-04-21 00:14:59 UTC (rev 276333)
@@ -29,6 +29,7 @@
 #include "Document.h"
 
 #include "AXObjectCache.h"
+#include "ApplicationManifest.h"
 #include "Attr.h"
 #include "BeforeUnloadEvent.h"
 #include "CDATASection.h"
@@ -3853,18 +3854,22 @@
     }
 }
 
-void Document::processThemeColor(const String& themeColorString)
+void Document::processMetaElementThemeColor(const String& themeColorString)
 {
-    auto themeColor = CSSParser::parseColor(themeColorString);
-    if (themeColor == m_themeColor)
+    auto oldThemeColor = themeColor();
+    m_metaElementThemeColor = CSSParser::parseColor(themeColorString);
+    if (themeColor() == oldThemeColor)
         return;
 
-    m_themeColor = WTFMove(themeColor);
+    themeColorChanged();
+}
 
+void Document::themeColorChanged()
+{
     scheduleRenderingUpdate({ });
 
     if (auto* page = this->page())
-        page->chrome().client().themeColorChanged(m_themeColor);
+        page->chrome().client().themeColorChanged();
 
 #if ENABLE(RUBBER_BANDING)
     if (auto* view = renderView()) {
@@ -3978,6 +3983,20 @@
     setReferrerPolicy(referrerPolicy.value());
 }
 
+#if ENABLE(APPLICATION_MANIFEST)
+
+void Document::processApplicationManifest(const ApplicationManifest& applicationManifest)
+{
+    auto oldThemeColor = themeColor();
+    m_applicationManifestThemeColor = applicationManifest.themeColor;
+    if (themeColor() == oldThemeColor)
+        return;
+
+    themeColorChanged();
+}
+
+#endif // ENABLE(APPLICATION_MANIFEST)
+
 MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const LayoutPoint& documentPoint, const PlatformMouseEvent& event)
 {
     if (!hasLivingRenderTree())

Modified: trunk/Source/WebCore/dom/Document.h (276332 => 276333)


--- trunk/Source/WebCore/dom/Document.h	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/dom/Document.h	2021-04-21 00:14:59 UTC (rev 276333)
@@ -234,6 +234,7 @@
 class XPathNSResolver;
 class XPathResult;
 
+struct ApplicationManifest;
 struct BoundaryPoint;
 struct HighlightRangeData;
 struct IntersectionObserverData;
@@ -740,7 +741,7 @@
     Seconds timeSinceDocumentCreation() const { return MonotonicTime::now() - m_documentCreationTime; };
 #endif
 
-    const Color& themeColor() const { return m_themeColor; }
+    const Color& themeColor() const { return m_metaElementThemeColor.isValid() ? m_metaElementThemeColor : m_applicationManifestThemeColor; }
 
     void setTextColor(const Color& color) { m_textColor = color; }
     const Color& textColor() const { return m_textColor; }
@@ -909,12 +910,16 @@
     void processDisabledAdaptations(const String& adaptations);
     void updateViewportArguments();
     void processReferrerPolicy(const String& policy, ReferrerPolicySource);
-    void processThemeColor(const String& themeColor);
+    void processMetaElementThemeColor(const String& themeColor);
 
 #if ENABLE(DARK_MODE_CSS)
     void processColorScheme(const String& colorScheme);
 #endif
 
+#if ENABLE(APPLICATION_MANIFEST)
+    void processApplicationManifest(const ApplicationManifest&);
+#endif
+
     // Returns the owning element in the parent document.
     // Returns nullptr if this is the top level document.
     WEBCORE_EXPORT HTMLFrameOwnerElement* ownerElement() const;
@@ -1670,6 +1675,8 @@
     void updateTitle(const StringWithDirection&);
     void updateBaseURL();
 
+    void themeColorChanged();
+
     void invalidateAccessKeyCacheSlowCase();
     void buildAccessKeyCache();
 
@@ -1790,7 +1797,9 @@
 
     std::unique_ptr<FormController> m_formController;
 
-    Color m_themeColor;
+    Color m_metaElementThemeColor;
+    Color m_applicationManifestThemeColor;
+
     Color m_textColor { Color::black };
     Color m_linkColor;
     Color m_visitedLinkColor;

Modified: trunk/Source/WebCore/html/HTMLMetaElement.cpp (276332 => 276333)


--- trunk/Source/WebCore/html/HTMLMetaElement.cpp	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/html/HTMLMetaElement.cpp	2021-04-21 00:14:59 UTC (rev 276333)
@@ -57,7 +57,7 @@
     HTMLElement::attributeChanged(name, oldValue, newValue, reason);
 
     if (name == nameAttr && equalLettersIgnoringASCIICase(oldValue, "theme-color") && !equalLettersIgnoringASCIICase(newValue, "theme-color"))
-        document().processThemeColor(emptyString());
+        document().processMetaElementThemeColor(emptyString());
 }
 
 void HTMLMetaElement::parseAttribute(const QualifiedName& name, const AtomString& value)
@@ -90,7 +90,7 @@
     HTMLElement::removedFromAncestor(removalType, oldParentOfRemovedTree);
 
     if (!isConnected() && equalLettersIgnoringASCIICase(name(), "theme-color"))
-        oldParentOfRemovedTree.document().processThemeColor(emptyString());
+        oldParentOfRemovedTree.document().processMetaElementThemeColor(emptyString());
 }
 
 void HTMLMetaElement::process()
@@ -112,7 +112,7 @@
         document().processColorScheme(contentValue);
 #endif
     else if (equalLettersIgnoringASCIICase(name(), "theme-color"))
-        document().processThemeColor(contentValue);
+        document().processMetaElementThemeColor(contentValue);
 #if PLATFORM(IOS_FAMILY)
     else if (equalLettersIgnoringASCIICase(name(), "format-detection"))
         document().processFormatDetection(contentValue);

Modified: trunk/Source/WebCore/loader/cache/CachedApplicationManifest.cpp (276332 => 276333)


--- trunk/Source/WebCore/loader/cache/CachedApplicationManifest.cpp	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/loader/cache/CachedApplicationManifest.cpp	2021-04-21 00:14:59 UTC (rev 276333)
@@ -59,12 +59,12 @@
     return m_decoder->encoding().name();
 }
 
-Optional<ApplicationManifest> CachedApplicationManifest::process(const URL& manifestURL, const URL& documentURL, RefPtr<ScriptExecutionContext> scriptExecutionContext)
+Optional<ApplicationManifest> CachedApplicationManifest::process(const URL& manifestURL, const URL& documentURL, Document* document)
 {
     if (!m_text)
         return WTF::nullopt;
-    if (scriptExecutionContext)
-        return ApplicationManifestParser::parse(*scriptExecutionContext, *m_text, manifestURL, documentURL);
+    if (document)
+        return ApplicationManifestParser::parse(*document, *m_text, manifestURL, documentURL);
     return ApplicationManifestParser::parse(*m_text, manifestURL, documentURL);
 }
 

Modified: trunk/Source/WebCore/loader/cache/CachedApplicationManifest.h (276332 => 276333)


--- trunk/Source/WebCore/loader/cache/CachedApplicationManifest.h	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/loader/cache/CachedApplicationManifest.h	2021-04-21 00:14:59 UTC (rev 276333)
@@ -33,7 +33,7 @@
 
 namespace WebCore {
 
-class ScriptExecutionContext;
+class Document;
 class TextResourceDecoder;
 
 class CachedApplicationManifest final : public CachedResource {
@@ -40,7 +40,7 @@
 public:
     CachedApplicationManifest(CachedResourceRequest&&, const PAL::SessionID&, const CookieJar*);
 
-    Optional<struct ApplicationManifest> process(const URL& manifestURL, const URL& documentURL, RefPtr<ScriptExecutionContext> = nullptr);
+    Optional<struct ApplicationManifest> process(const URL& manifestURL, const URL& documentURL, Document* = nullptr);
 
 private:
     void finishLoading(SharedBuffer*, const NetworkLoadMetrics&) override;

Modified: trunk/Source/WebCore/page/ChromeClient.h (276332 => 276333)


--- trunk/Source/WebCore/page/ChromeClient.h	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/page/ChromeClient.h	2021-04-21 00:14:59 UTC (rev 276333)
@@ -231,8 +231,8 @@
 
     virtual Color underlayColor() const { return Color(); }
 
-    virtual void themeColorChanged(Color) const { }
-    virtual void pageExtendedBackgroundColorDidChange(Color) const { }
+    virtual void themeColorChanged() const { }
+    virtual void pageExtendedBackgroundColorDidChange() const { }
 
     virtual void exceededDatabaseQuota(Frame&, const String& databaseName, DatabaseDetails) = 0;
 

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (276332 => 276333)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2021-04-21 00:14:59 UTC (rev 276333)
@@ -4008,7 +4008,7 @@
     m_rootExtendedBackgroundColor = extendedBackgroundColor;
     
     if (extendedBackgroundColorChanged) {
-        page().chrome().client().pageExtendedBackgroundColorDidChange(m_rootExtendedBackgroundColor);
+        page().chrome().client().pageExtendedBackgroundColorDidChange();
         
 #if ENABLE(RUBBER_BANDING)
         updateLayerForOverhangAreasBackgroundColor();

Modified: trunk/Source/WebKit/ChangeLog (276332 => 276333)


--- trunk/Source/WebKit/ChangeLog	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebKit/ChangeLog	2021-04-21 00:14:59 UTC (rev 276333)
@@ -1,3 +1,22 @@
+2021-04-20  Devin Rousso  <[email protected]>
+
+        Parse `theme_color` in web application manifests and pass it along to `-[WKWebView themeColor]`
+        https://bugs.webkit.org/show_bug.cgi?id=224796
+
+        Reviewed by Darin Adler.
+
+        * UIProcess/API/Cocoa/_WKApplicationManifest.h:
+        * UIProcess/API/Cocoa/_WKApplicationManifest.mm:
+        (-[_WKApplicationManifest initWithCoder:]):
+        (-[_WKApplicationManifest encodeWithCoder:]):
+        (-[_WKApplicationManifest themeColor]): Added.
+
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::themeColorChanged const):
+        (WebKit::WebChromeClient::pageExtendedBackgroundColorDidChange const):
+        Drive-by: Remove the `Color` parameter since it's not actually used in the WebProcess.
+
 2021-04-20  Michael Catanzaro  <[email protected]>
 
         Lots of spurious -Wnonnull warnings with GCC 11

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.h (276332 => 276333)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.h	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.h	2021-04-21 00:14:59 UTC (rev 276333)
@@ -26,6 +26,12 @@
 #import <Foundation/Foundation.h>
 #import <WebKit/WKFoundation.h>
 
+#if TARGET_OS_IPHONE
+@class UIColor;
+#else
+@class NSColor;
+#endif
+
 NS_ASSUME_NONNULL_BEGIN
 
 typedef NS_ENUM(NSInteger, _WKApplicationManifestDisplayMode) {
@@ -45,6 +51,12 @@
 @property (nonatomic, readonly, copy) NSURL *startURL;
 @property (nonatomic, readonly) _WKApplicationManifestDisplayMode displayMode;
 
+#if TARGET_OS_IPHONE
+@property (nonatomic, readonly, nullable, copy) UIColor *themeColor WK_API_AVAILABLE(ios(WK_IOS_TBA));
+#else
+@property (nonatomic, readonly, nullable, copy) NSColor *themeColor WK_API_AVAILABLE(macos(WK_MAC_TBA));
+#endif
+
 + (_WKApplicationManifest *)applicationManifestFromJSON:(NSString *)json manifestURL:(nullable NSURL *)manifestURL documentURL:(nullable NSURL *)documentURL;
 
 @end

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.mm (276332 => 276333)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.mm	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.mm	2021-04-21 00:14:59 UTC (rev 276333)
@@ -26,10 +26,21 @@
 #import "config.h"
 #import "_WKApplicationManifestInternal.h"
 
+#import "CocoaColor.h"
 #import <WebCore/ApplicationManifest.h>
 #import <WebCore/ApplicationManifestParser.h>
+#import <WebCore/Color.h>
+#import <WebCore/ColorCocoa.h>
 #import <WebCore/WebCoreObjCExtras.h>
 
+#if PLATFORM(IOS_FAMILY)
+#import "UIKitSPI.h"
+#endif
+
+#if PLATFORM(MAC)
+#import "AppKitSPI.h"
+#endif
+
 @implementation _WKApplicationManifest
 
 #if ENABLE(APPLICATION_MANIFEST)
@@ -47,6 +58,7 @@
     NSURL *scopeURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:@"scope"];
     NSInteger display = [aDecoder decodeIntegerForKey:@"display"];
     NSURL *startURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:@"start_url"];
+    CocoaColor *themeColor = [aDecoder decodeObjectOfClass:[CocoaColor class] forKey:@"theme_color"];
 
     WebCore::ApplicationManifest coreApplicationManifest {
         WTF::String(name),
@@ -54,7 +66,8 @@
         WTF::String(description),
         URL(scopeURL),
         static_cast<WebCore::ApplicationManifest::Display>(display),
-        URL(startURL)
+        URL(startURL),
+        WebCore::Color(themeColor.CGColor),
     };
 
     API::Object::constructInWrapper<API::ApplicationManifest>(self, WTFMove(coreApplicationManifest));
@@ -80,6 +93,7 @@
     [aCoder encodeObject:self.scope forKey:@"scope"];
     [aCoder encodeInteger:static_cast<NSInteger>(_applicationManifest->applicationManifest().display) forKey:@"display"];
     [aCoder encodeObject:self.startURL forKey:@"start_url"];
+    [aCoder encodeObject:self.themeColor forKey:@"theme_color"];
 }
 
 + (_WKApplicationManifest *)applicationManifestFromJSON:(NSString *)json manifestURL:(NSURL *)manifestURL documentURL:(NSURL *)documentURL
@@ -123,6 +137,11 @@
     return _applicationManifest->applicationManifest().startURL;
 }
 
+- (CocoaColor *)themeColor
+{
+    return WebCore::platformColor(_applicationManifest->applicationManifest().themeColor);
+}
+
 - (_WKApplicationManifestDisplayMode)displayMode
 {
     switch (_applicationManifest->applicationManifest().display) {
@@ -186,6 +205,11 @@
     return nil;
 }
 
+- (CocoaColor *)themeColor
+{
+    return nil;
+}
+
 - (_WKApplicationManifestDisplayMode)displayMode
 {
     return _WKApplicationManifestDisplayModeBrowser;

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (276332 => 276333)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-04-21 00:14:59 UTC (rev 276333)
@@ -654,7 +654,7 @@
     float topContentInset() const { return m_topContentInset; }
     void setTopContentInset(float);
 
-    // Corresponds to the web content's `<meta name="theme-color" content="...">`.
+    // Corresponds to the web content's `<meta name="theme-color">` or application manifest's `"theme_color"`.
     WebCore::Color themeColor() const { return m_themeColor; }
 
     WebCore::Color underlayColor() const { return m_underlayColor; }

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (276332 => 276333)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2021-04-21 00:14:59 UTC (rev 276333)
@@ -1154,12 +1154,12 @@
     return m_page.underlayColor();
 }
 
-void WebChromeClient::themeColorChanged(Color /* themeColor */) const
+void WebChromeClient::themeColorChanged() const
 {
     m_page.themeColorChanged();
 }
 
-void WebChromeClient::pageExtendedBackgroundColorDidChange(Color /* backgroundColor */) const
+void WebChromeClient::pageExtendedBackgroundColorDidChange() const
 {
     m_page.pageExtendedBackgroundColorDidChange();
 }

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (276332 => 276333)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2021-04-21 00:14:59 UTC (rev 276333)
@@ -328,8 +328,8 @@
 
     WebCore::Color underlayColor() const final;
 
-    void themeColorChanged(WebCore::Color) const final;
-    void pageExtendedBackgroundColorDidChange(WebCore::Color) const final;
+    void themeColorChanged() const final;
+    void pageExtendedBackgroundColorDidChange() const final;
     
     void wheelEventHandlersChanged(bool) final;
 

Modified: trunk/Tools/ChangeLog (276332 => 276333)


--- trunk/Tools/ChangeLog	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Tools/ChangeLog	2021-04-21 00:14:59 UTC (rev 276333)
@@ -1,3 +1,25 @@
+2021-04-20  Devin Rousso  <[email protected]>
+
+        Parse `theme_color` in web application manifests and pass it along to `-[WKWebView themeColor]`
+        https://bugs.webkit.org/show_bug.cgi?id=224796
+
+        Reviewed by Darin Adler.
+
+        * TestWebKitAPI/Tests/WebCore/ApplicationManifestParser.cpp:
+        (ApplicationManifestParserTest::testThemeColor): Added.
+        (TEST_F.ApplicationManifestParserTest.ThemeColor): Added.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm:
+        (TEST.ApplicationManifestBasic):
+        (TEST.ApplicationManifestCoding):
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewThemeColor.mm: Renamed from Tools/TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm.
+        (TEST.WKWebViewThemeColor.ApplicationManifest):
+        (TEST.WKWebViewThemeColor.MetaElementOverridesApplicationManifest):
+        Rename this file now that it also deals with web application manifest (in addition to `<meta name="theme-color">`).
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+
 2021-04-20  Tim Horton  <[email protected]>
 
         MacCatalyst tests crash on NSInternalInconsistencyException, reason: NSApplication has not been created yet

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (276332 => 276333)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-04-21 00:14:59 UTC (rev 276333)
@@ -866,7 +866,7 @@
 		93F7E86F14DC8E5C00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */; };
 		950E4CC1252E75240071659F /* iOSStylusSupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = 950E4CC0252E75230071659F /* iOSStylusSupport.mm */; };
 		953ABB3525C0D682004C8B73 /* PageExtendedBackgroundColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 953ABB3425C0D681004C8B73 /* PageExtendedBackgroundColor.mm */; };
-		95A524952581A10D00461FE9 /* HTMLMetaThemeColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A524942581A10D00461FE9 /* HTMLMetaThemeColor.mm */; };
+		95A524952581A10D00461FE9 /* WKWebViewThemeColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A524942581A10D00461FE9 /* WKWebViewThemeColor.mm */; };
 		95B6B3B7251EBF2F00FC4382 /* MediaDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95B6B3B6251EBF2F00FC4382 /* MediaDocument.mm */; };
 		9984FACC1CFFAF60008D198C /* WKWebViewTextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9984FACA1CFFAEEE008D198C /* WKWebViewTextInput.mm */; };
 		9984FACE1CFFB090008D198C /* editable-body.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9984FACD1CFFB038008D198C /* editable-body.html */; };
@@ -2554,7 +2554,7 @@
 		93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp; sourceTree = "<group>"; };
 		950E4CC0252E75230071659F /* iOSStylusSupport.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSStylusSupport.mm; sourceTree = "<group>"; };
 		953ABB3425C0D681004C8B73 /* PageExtendedBackgroundColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PageExtendedBackgroundColor.mm; sourceTree = "<group>"; };
-		95A524942581A10D00461FE9 /* HTMLMetaThemeColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLMetaThemeColor.mm; sourceTree = "<group>"; };
+		95A524942581A10D00461FE9 /* WKWebViewThemeColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewThemeColor.mm; sourceTree = "<group>"; };
 		95B6B3B6251EBF2F00FC4382 /* MediaDocument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaDocument.mm; sourceTree = "<group>"; };
 		9984FACA1CFFAEEE008D198C /* WKWebViewTextInput.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewTextInput.mm; sourceTree = "<group>"; };
 		9984FACD1CFFB038008D198C /* editable-body.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "editable-body.html"; sourceTree = "<group>"; };
@@ -3409,7 +3409,6 @@
 				07E1F6A01FFC3A080096C7EC /* GetDisplayMedia.mm */,
 				2DADF26221CB8F32003D3E3A /* GetResourceData.mm */,
 				465E2806255B2A690063A787 /* GPUProcess.mm */,
-				95A524942581A10D00461FE9 /* HTMLMetaThemeColor.mm */,
 				51AF23DE1EF1A3720072F281 /* IconLoadingDelegate.mm */,
 				EB230D3E245E726300C66AD1 /* IDBCheckpointWAL.mm */,
 				510477751D298E03009747EB /* IDBDeleteRecovery.mm */,
@@ -3608,6 +3607,7 @@
 				93F56DA81E5F9181003EDE84 /* WKWebViewSnapshot.mm */,
 				CD7F89DB22A86CDA00D683AE /* WKWebViewSuspendAllMediaPlayback.mm */,
 				9984FACA1CFFAEEE008D198C /* WKWebViewTextInput.mm */,
+				95A524942581A10D00461FE9 /* WKWebViewThemeColor.mm */,
 			);
 			name = "WebKit Cocoa";
 			path = WebKitCocoa;
@@ -5431,7 +5431,6 @@
 				7CCE7EFA1A411AE600447C4C /* HitTestResultNodeHandle.cpp in Sources */,
 				7CCE7EC11A411A7E00447C4C /* HTMLCollectionNamedItem.mm in Sources */,
 				7CCE7EC21A411A7E00447C4C /* HTMLFormCollectionNamedItem.mm in Sources */,
-				95A524952581A10D00461FE9 /* HTMLMetaThemeColor.mm in Sources */,
 				7C83E0501D0A641800FEBCF3 /* HTMLParserIdioms.cpp in Sources */,
 				5CA1DEC81F71F70100E71BD3 /* HTTPHeaderField.cpp in Sources */,
 				46FA2FEE23846CA5000CCB0C /* HTTPHeaderMap.cpp in Sources */,
@@ -5831,6 +5830,7 @@
 				93F56DA91E5F919D003EDE84 /* WKWebViewSnapshot.mm in Sources */,
 				CD7F89DC22A86CDA00D683AE /* WKWebViewSuspendAllMediaPlayback.mm in Sources */,
 				9984FACC1CFFAF60008D198C /* WKWebViewTextInput.mm in Sources */,
+				95A524952581A10D00461FE9 /* WKWebViewThemeColor.mm in Sources */,
 				7C74C8FA22DFBA9600DA2DAB /* WTFStringUtilities.cpp in Sources */,
 				C14D304624B4C3BA00480387 /* XPCEndpoint.mm in Sources */,
 				9C64DC321D76198A004B598E /* YouTubePluginReplacement.cpp in Sources */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ApplicationManifestParser.cpp (276332 => 276333)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ApplicationManifestParser.cpp	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ApplicationManifestParser.cpp	2021-04-21 00:14:59 UTC (rev 276333)
@@ -127,6 +127,13 @@
         testScope(rawJSON, String(), expectedValue);
     }
 
+    void testThemeColor(const String& rawJSON, const Color& expectedValue)
+    {
+        auto manifest = parseTopLevelProperty("theme_color", rawJSON);
+        auto value = manifest.themeColor;
+        EXPECT_EQ(expectedValue, value);
+    }
+
 };
 
 static void assertManifestHasDefaultValues(const URL& manifestURL, const URL& documentURL, const ApplicationManifest& manifest)
@@ -289,6 +296,26 @@
     testScope("\"https://example.com/other\"", String("https://example.com/other/start-url"), "https://example.com/other");
 }
 
+TEST_F(ApplicationManifestParserTest, ThemeColor)
+{
+    testThemeColor("123", Color());
+    testThemeColor("null", Color());
+    testThemeColor("true", Color());
+    testThemeColor("{ }", Color());
+    testThemeColor("[ ]", Color());
+    testThemeColor("\"\"", Color());
+    testThemeColor("\"garbage string\"", Color());
+
+    testThemeColor("\"red\"", Color::red);
+    testThemeColor("\"#f00\"", Color::red);
+    testThemeColor("\"#ff0000\"", Color::red);
+    testThemeColor("\"#ff0000ff\"", Color::red);
+    testThemeColor("\"rgb(255, 0, 0)\"", Color::red);
+    testThemeColor("\"rgba(255, 0, 0, 1)\"", Color::red);
+    testThemeColor("\"hsl(0, 100%, 50%)\"", Color::red);
+    testThemeColor("\"hsla(0, 100%, 50%, 1)\"", Color::red);
+}
+
 TEST_F(ApplicationManifestParserTest, Whitespace)
 {
     auto manifest = parseString("  { \"name\": \"PASS\" }\n"_s);

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm (276332 => 276333)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm	2021-04-21 00:14:59 UTC (rev 276333)
@@ -37,9 +37,11 @@
 
 namespace TestWebKitAPI {
 
+constexpr CGFloat redColorComponents[4] = { 1, 0, 0, 1 };
+
 TEST(WebKit, ApplicationManifestCoding)
 {
-    auto jsonString = @"{ \"name\": \"TestName\", \"short_name\": \"TestShortName\", \"description\": \"TestDescription\", \"scope\": \"https://test.com/app\", \"start_url\": \"https://test.com/app/index.html\", \"display\": \"minimal-ui\" }";
+    auto jsonString = @"{ \"name\": \"TestName\", \"short_name\": \"TestShortName\", \"description\": \"TestDescription\", \"scope\": \"https://test.com/app\", \"start_url\": \"https://test.com/app/index.html\", \"display\": \"minimal-ui\", \"theme_color\": \"red\" }";
     RetainPtr<_WKApplicationManifest> manifest { [_WKApplicationManifest applicationManifestFromJSON:jsonString manifestURL:[NSURL URLWithString:@"https://test.com/manifest.json"] documentURL:[NSURL URLWithString:@"https://test.com/"]] };
 
     NSData *data = "" archivedDataWithRootObject:manifest.get() requiringSecureCoding:YES error:nullptr];
@@ -52,6 +54,10 @@
     EXPECT_STREQ("https://test.com/app", manifest.get().scope.absoluteString.UTF8String);
     EXPECT_STREQ("https://test.com/app/index.html", manifest.get().startURL.absoluteString.UTF8String);
     EXPECT_EQ(_WKApplicationManifestDisplayModeMinimalUI,  manifest.get().displayMode);
+
+    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+    auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
+    EXPECT_TRUE(CGColorEqualToColor(manifest.get().themeColor.CGColor, redColor.get()));
 }
 
 TEST(WebKit, ApplicationManifestBasic)
@@ -90,6 +96,7 @@
         @"description": @"Hello.",
         @"start_url": @"http://example.com/app/start",
         @"scope": @"http://example.com/app",
+        @"theme_color": @"red",
     };
     NSString *htmlString = [NSString stringWithFormat:@"<link rel=\"manifest\" href="" [[NSJSONSerialization dataWithJSONObject:manifestObject options:0 error:nil] base64EncodedStringWithOptions:0]];
     [webView loadHTMLString:htmlString baseURL:[NSURL URLWithString:@"http://example.com/app/index"]];
@@ -100,6 +107,11 @@
         EXPECT_TRUE([manifest.applicationDescription isEqualToString:@"Hello."]);
         EXPECT_TRUE([manifest.startURL isEqual:[NSURL URLWithString:@"http://example.com/app/start"]]);
         EXPECT_TRUE([manifest.scope isEqual:[NSURL URLWithString:@"http://example.com/app"]]);
+
+        auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+        auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
+        EXPECT_TRUE(CGColorEqualToColor(manifest.themeColor.CGColor, redColor.get()));
+
         done = true;
     }];
     Util::run(&done);

Deleted: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm (276332 => 276333)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm	2021-04-21 00:08:15 UTC (rev 276332)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm	2021-04-21 00:14:59 UTC (rev 276333)
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-
-#import "CocoaColor.h"
-#import "TestCocoa.h"
-#import "TestWKWebView.h"
-#import <WebKit/WKPreferencesPrivate.h>
-#import <WebKit/WKWebViewPrivate.h>
-#import <WebKit/_WKInternalDebugFeature.h>
-#import <wtf/RetainPtr.h>
-
-#define EXPECT_NSSTRING_EQ(expected, actual) \
-    EXPECT_TRUE([actual isKindOfClass:[NSString class]]); \
-    EXPECT_WK_STREQ(expected, (NSString *)actual);
-
-constexpr CGFloat redColorComponents[4] = { 1, 0, 0, 1 };
-constexpr CGFloat blueColorComponents[4] = { 0, 0, 1, 1 };
-
-TEST(HTMLMetaThemeColor, OnLoad)
-{
-    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
-    EXPECT_TRUE(![webView themeColor]);
-
-    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'>"];
-
-    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
-    auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
-    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, redColor.get()));
-
-    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='not-theme-color' content='red'>"];
-
-    EXPECT_TRUE(![webView themeColor]);
-}
-
-TEST(HTMLMetaThemeColor, MultipleTags)
-{
-    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
-    EXPECT_TRUE(![webView themeColor]);
-
-    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'><meta name='theme-color' content='blue'>"];
-
-    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
-    auto blueColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), blueColorComponents));
-    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, blueColor.get()));
-}
-
-@interface WKWebViewThemeColorObserver : NSObject
-
-- (instancetype)initWithWebView:(WKWebView *)webView;
-
-@property (nonatomic, readonly) WKWebView *webView;
-@property (nonatomic, copy) NSString *state;
-
-@end
-
-@implementation WKWebViewThemeColorObserver
-
-- (instancetype)initWithWebView:(WKWebView *)webView
-{
-    if (!(self = [super init]))
-        return nil;
-
-    _state = @"before-init";
-
-    _webView = webView;
-    [_webView addObserver:self forKeyPath:@"themeColor" options:NSKeyValueObservingOptionInitial context:nil];
-
-    return self;
-}
-
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
-{
-    if ([_state isEqualToString:@"before-init"]) {
-        _state = @"after-init";
-        return;
-    }
-
-    if ([_state isEqualToString:@"before-load"]) {
-        _state = @"after-load";
-        return;
-    }
-
-    if ([_state isEqualToString:@"before-content-change"]) {
-        _state = @"after-content-change";
-        return;
-    }
-
-    if ([_state isEqualToString:@"before-name-change-not-theme-color"]) {
-        _state = @"after-name-change-not-theme-color";
-        return;
-    }
-
-    if ([_state isEqualToString:@"before-name-change-theme-color"]) {
-        _state = @"after-name-change-theme-color";
-        return;
-    }
-
-    if ([_state isEqualToString:@"before-node-removed"]) {
-        _state = @"after-node-removed";
-        return;
-    }
-
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-@end
-
-TEST(HTMLMetaThemeColor, KVO)
-{
-    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
-    auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
-    auto blueColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), blueColorComponents));
-
-    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
-    auto themeColorObserver = adoptNS([[WKWebViewThemeColorObserver alloc] initWithWebView:webView.get()]);
-    EXPECT_NSSTRING_EQ("after-init", [themeColorObserver state]);
-    EXPECT_TRUE(![webView themeColor]);
-
-    [themeColorObserver setState:@"before-load"];
-    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'>"];
-    EXPECT_NSSTRING_EQ("after-load", [themeColorObserver state]);
-    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, redColor.get()));
-
-    [themeColorObserver setState:@"before-content-change"];
-    [webView objectByEvaluatingJavaScript:@"document.querySelector('meta').setAttribute('content', 'blue')"];
-    [webView waitForNextPresentationUpdate];
-    EXPECT_NSSTRING_EQ("after-content-change", [themeColorObserver state]);
-    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, blueColor.get()));
-
-    [themeColorObserver setState:@"before-name-change-not-theme-color"];
-    [webView objectByEvaluatingJavaScript:@"document.querySelector('meta').setAttribute('name', 'not-theme-color')"];
-    [webView waitForNextPresentationUpdate];
-    EXPECT_NSSTRING_EQ("after-name-change-not-theme-color", [themeColorObserver state]);
-    EXPECT_TRUE(![webView themeColor]);
-
-    [themeColorObserver setState:@"before-name-change-theme-color"];
-    [webView objectByEvaluatingJavaScript:@"document.querySelector('meta').setAttribute('name', 'theme-color')"];
-    [webView waitForNextPresentationUpdate];
-    EXPECT_NSSTRING_EQ("after-name-change-theme-color", [themeColorObserver state]);
-    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, blueColor.get()));
-
-    [themeColorObserver setState:@"before-node-removed"];
-    [webView objectByEvaluatingJavaScript:@"document.querySelector('meta').remove()"];
-    [webView waitForNextPresentationUpdate];
-    EXPECT_NSSTRING_EQ("after-node-removed", [themeColorObserver state]);
-    EXPECT_TRUE(![webView themeColor]);
-}
-
-#if PLATFORM(IOS_FAMILY)
-
-// There's no API/SPI to get the background color of the scroll area on macOS.
-
-enum class UseThemeColorForScrollAreaBackgroundColor : bool { Yes, No };
-static RetainPtr<TestWKWebView> createWebView(UseThemeColorForScrollAreaBackgroundColor useThemeColorForScrollAreaBackgroundColor)
-{
-    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    for (_WKInternalDebugFeature *feature in [WKPreferences _internalDebugFeatures]) {
-        if ([feature.key isEqualToString:@"UseThemeColorForScrollAreaBackgroundColor"]) {
-            [[configuration preferences] _setEnabled:(useThemeColorForScrollAreaBackgroundColor == UseThemeColorForScrollAreaBackgroundColor::Yes) forInternalDebugFeature:feature];
-            break;
-        }
-    }
-
-    return adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
-}
-
-TEST(HTMLMetaThemeColor, ExperimentalUseThemeColorForScrollAreaBackgroundColor)
-{
-    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
-    auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
-    auto blueColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), blueColorComponents));
-
-    auto webViewWithoutThemeColorForScrollAreaBackgroundColor = createWebView(UseThemeColorForScrollAreaBackgroundColor::No);
-    EXPECT_TRUE(![webViewWithoutThemeColorForScrollAreaBackgroundColor themeColor]);
-
-    [webViewWithoutThemeColorForScrollAreaBackgroundColor synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<body style='background-color: blue'>"];
-    EXPECT_TRUE(![webViewWithoutThemeColorForScrollAreaBackgroundColor themeColor]);
-    EXPECT_TRUE(CGColorEqualToColor([webViewWithoutThemeColorForScrollAreaBackgroundColor scrollView].backgroundColor.CGColor, blueColor.get()));
-
-    [webViewWithoutThemeColorForScrollAreaBackgroundColor synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'><body style='background-color: blue'>"];
-    EXPECT_TRUE(CGColorEqualToColor([webViewWithoutThemeColorForScrollAreaBackgroundColor themeColor].CGColor, redColor.get()));
-    EXPECT_TRUE(CGColorEqualToColor([webViewWithoutThemeColorForScrollAreaBackgroundColor scrollView].backgroundColor.CGColor, blueColor.get()));
-
-    auto webViewWithThemeColorForScrollAreaBackgroundColor = createWebView(UseThemeColorForScrollAreaBackgroundColor::Yes);
-    EXPECT_TRUE(![webViewWithThemeColorForScrollAreaBackgroundColor themeColor]);
-
-    [webViewWithThemeColorForScrollAreaBackgroundColor synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<body style='background-color: blue'>"];
-    EXPECT_TRUE(![webViewWithThemeColorForScrollAreaBackgroundColor themeColor]);
-    EXPECT_TRUE(CGColorEqualToColor([webViewWithThemeColorForScrollAreaBackgroundColor scrollView].backgroundColor.CGColor, blueColor.get()));
-
-    [webViewWithThemeColorForScrollAreaBackgroundColor synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'><body style='background-color: blue'>"];
-    EXPECT_TRUE(CGColorEqualToColor([webViewWithThemeColorForScrollAreaBackgroundColor themeColor].CGColor, redColor.get()));
-    EXPECT_TRUE(CGColorEqualToColor([webViewWithThemeColorForScrollAreaBackgroundColor scrollView].backgroundColor.CGColor, redColor.get()));
-}
-
-#endif // PLATFORM(IOS_FAMILY)

Copied: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewThemeColor.mm (from rev 276332, trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm) (0 => 276333)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewThemeColor.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewThemeColor.mm	2021-04-21 00:14:59 UTC (rev 276333)
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#import "CocoaColor.h"
+#import "TestCocoa.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/_WKApplicationManifest.h>
+#import <WebKit/_WKInternalDebugFeature.h>
+#import <wtf/RetainPtr.h>
+
+#define EXPECT_NSSTRING_EQ(expected, actual) \
+    EXPECT_TRUE([actual isKindOfClass:[NSString class]]); \
+    EXPECT_WK_STREQ(expected, (NSString *)actual);
+
+constexpr CGFloat redColorComponents[4] = { 1, 0, 0, 1 };
+constexpr CGFloat blueColorComponents[4] = { 0, 0, 1, 1 };
+
+TEST(WKWebViewThemeColor, MetaElementOnLoad)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    EXPECT_TRUE(![webView themeColor]);
+
+    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'>"];
+
+    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+    auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
+    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, redColor.get()));
+
+    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='not-theme-color' content='red'>"];
+
+    EXPECT_TRUE(![webView themeColor]);
+}
+
+TEST(WKWebViewThemeColor, MultipleMetaElements)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    EXPECT_TRUE(![webView themeColor]);
+
+    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'><meta name='theme-color' content='blue'>"];
+
+    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+    auto blueColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), blueColorComponents));
+    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, blueColor.get()));
+}
+
+@interface WKWebViewThemeColorObserver : NSObject
+
+- (instancetype)initWithWebView:(WKWebView *)webView;
+
+@property (nonatomic, readonly) WKWebView *webView;
+@property (nonatomic, copy) NSString *state;
+
+@end
+
+@implementation WKWebViewThemeColorObserver
+
+- (instancetype)initWithWebView:(WKWebView *)webView
+{
+    if (!(self = [super init]))
+        return nil;
+
+    _state = @"before-init";
+
+    _webView = webView;
+    [_webView addObserver:self forKeyPath:@"themeColor" options:NSKeyValueObservingOptionInitial context:nil];
+
+    return self;
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+    if ([_state isEqualToString:@"before-init"]) {
+        _state = @"after-init";
+        return;
+    }
+
+    if ([_state isEqualToString:@"before-load"]) {
+        _state = @"after-load";
+        return;
+    }
+
+    if ([_state isEqualToString:@"before-content-change"]) {
+        _state = @"after-content-change";
+        return;
+    }
+
+    if ([_state isEqualToString:@"before-name-change-not-theme-color"]) {
+        _state = @"after-name-change-not-theme-color";
+        return;
+    }
+
+    if ([_state isEqualToString:@"before-name-change-theme-color"]) {
+        _state = @"after-name-change-theme-color";
+        return;
+    }
+
+    if ([_state isEqualToString:@"before-node-removed"]) {
+        _state = @"after-node-removed";
+        return;
+    }
+
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+@end
+
+TEST(WKWebViewThemeColor, KVO)
+{
+    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+    auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
+    auto blueColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), blueColorComponents));
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    auto themeColorObserver = adoptNS([[WKWebViewThemeColorObserver alloc] initWithWebView:webView.get()]);
+    EXPECT_NSSTRING_EQ("after-init", [themeColorObserver state]);
+    EXPECT_TRUE(![webView themeColor]);
+
+    [themeColorObserver setState:@"before-load"];
+    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'>"];
+    EXPECT_NSSTRING_EQ("after-load", [themeColorObserver state]);
+    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, redColor.get()));
+
+    [themeColorObserver setState:@"before-content-change"];
+    [webView objectByEvaluatingJavaScript:@"document.querySelector('meta').setAttribute('content', 'blue')"];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_NSSTRING_EQ("after-content-change", [themeColorObserver state]);
+    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, blueColor.get()));
+
+    [themeColorObserver setState:@"before-name-change-not-theme-color"];
+    [webView objectByEvaluatingJavaScript:@"document.querySelector('meta').setAttribute('name', 'not-theme-color')"];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_NSSTRING_EQ("after-name-change-not-theme-color", [themeColorObserver state]);
+    EXPECT_TRUE(![webView themeColor]);
+
+    [themeColorObserver setState:@"before-name-change-theme-color"];
+    [webView objectByEvaluatingJavaScript:@"document.querySelector('meta').setAttribute('name', 'theme-color')"];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_NSSTRING_EQ("after-name-change-theme-color", [themeColorObserver state]);
+    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, blueColor.get()));
+
+    [themeColorObserver setState:@"before-node-removed"];
+    [webView objectByEvaluatingJavaScript:@"document.querySelector('meta').remove()"];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_NSSTRING_EQ("after-node-removed", [themeColorObserver state]);
+    EXPECT_TRUE(![webView themeColor]);
+}
+
+#if ENABLE(APPLICATION_MANIFEST)
+
+TEST(WKWebViewThemeColor, ApplicationManifest)
+{
+    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+    auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    EXPECT_TRUE(![webView themeColor]);
+
+    NSDictionary *manifestObject = @{ @"name": @"Test", @"theme_color": @"red" };
+    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:[NSString stringWithFormat:@"<link rel='manifest' href=''>", [[NSJSONSerialization dataWithJSONObject:manifestObject options:0 error:nil] base64EncodedStringWithOptions:0]]];
+
+    static bool didGetApplicationManifest = false;
+    [webView _getApplicationManifestWithCompletionHandler:[&] (_WKApplicationManifest *manifest) {
+        EXPECT_TRUE(CGColorEqualToColor(manifest.themeColor.CGColor, redColor.get()));
+
+        didGetApplicationManifest = true;
+    }];
+    TestWebKitAPI::Util::run(&didGetApplicationManifest);
+
+    [webView waitForNextPresentationUpdate];
+    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, redColor.get()));
+}
+
+TEST(WKWebViewThemeColor, MetaElementOverridesApplicationManifest)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    EXPECT_TRUE(![webView themeColor]);
+
+    NSDictionary *manifestObject = @{ @"name": @"Test", @"theme_color": @"blue" };
+    [webView synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:[NSString stringWithFormat:@"<link rel='manifest' href=''><meta name='theme-color' content='red'>", [[NSJSONSerialization dataWithJSONObject:manifestObject options:0 error:nil] base64EncodedStringWithOptions:0]]];
+
+    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+    auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
+    EXPECT_TRUE(CGColorEqualToColor([webView themeColor].CGColor, redColor.get()));
+}
+
+#endif // ENABLE(APPLICATION_MANIFEST)
+
+#if PLATFORM(IOS_FAMILY)
+
+// There's no API/SPI to get the background color of the scroll area on macOS.
+
+enum class UseThemeColorForScrollAreaBackgroundColor : bool { Yes, No };
+static RetainPtr<TestWKWebView> createWebView(UseThemeColorForScrollAreaBackgroundColor useThemeColorForScrollAreaBackgroundColor)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    for (_WKInternalDebugFeature *feature in [WKPreferences _internalDebugFeatures]) {
+        if ([feature.key isEqualToString:@"UseThemeColorForScrollAreaBackgroundColor"]) {
+            [[configuration preferences] _setEnabled:(useThemeColorForScrollAreaBackgroundColor == UseThemeColorForScrollAreaBackgroundColor::Yes) forInternalDebugFeature:feature];
+            break;
+        }
+    }
+
+    return adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+}
+
+TEST(WKWebViewThemeColor, ExperimentalUseThemeColorForScrollAreaBackgroundColor)
+{
+    auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+    auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
+    auto blueColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), blueColorComponents));
+
+    auto webViewWithoutThemeColorForScrollAreaBackgroundColor = createWebView(UseThemeColorForScrollAreaBackgroundColor::No);
+    EXPECT_TRUE(![webViewWithoutThemeColorForScrollAreaBackgroundColor themeColor]);
+
+    [webViewWithoutThemeColorForScrollAreaBackgroundColor synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<body style='background-color: blue'>"];
+    EXPECT_TRUE(![webViewWithoutThemeColorForScrollAreaBackgroundColor themeColor]);
+    EXPECT_TRUE(CGColorEqualToColor([webViewWithoutThemeColorForScrollAreaBackgroundColor scrollView].backgroundColor.CGColor, blueColor.get()));
+
+    [webViewWithoutThemeColorForScrollAreaBackgroundColor synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'><body style='background-color: blue'>"];
+    EXPECT_TRUE(CGColorEqualToColor([webViewWithoutThemeColorForScrollAreaBackgroundColor themeColor].CGColor, redColor.get()));
+    EXPECT_TRUE(CGColorEqualToColor([webViewWithoutThemeColorForScrollAreaBackgroundColor scrollView].backgroundColor.CGColor, blueColor.get()));
+
+    auto webViewWithThemeColorForScrollAreaBackgroundColor = createWebView(UseThemeColorForScrollAreaBackgroundColor::Yes);
+    EXPECT_TRUE(![webViewWithThemeColorForScrollAreaBackgroundColor themeColor]);
+
+    [webViewWithThemeColorForScrollAreaBackgroundColor synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<body style='background-color: blue'>"];
+    EXPECT_TRUE(![webViewWithThemeColorForScrollAreaBackgroundColor themeColor]);
+    EXPECT_TRUE(CGColorEqualToColor([webViewWithThemeColorForScrollAreaBackgroundColor scrollView].backgroundColor.CGColor, blueColor.get()));
+
+    [webViewWithThemeColorForScrollAreaBackgroundColor synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:@"<meta name='theme-color' content='red'><body style='background-color: blue'>"];
+    EXPECT_TRUE(CGColorEqualToColor([webViewWithThemeColorForScrollAreaBackgroundColor themeColor].CGColor, redColor.get()));
+    EXPECT_TRUE(CGColorEqualToColor([webViewWithThemeColorForScrollAreaBackgroundColor scrollView].backgroundColor.CGColor, redColor.get()));
+}
+
+#endif // PLATFORM(IOS_FAMILY)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to