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)