Diff
Modified: trunk/Source/WebCore/ChangeLog (271919 => 271920)
--- trunk/Source/WebCore/ChangeLog 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/ChangeLog 2021-01-27 00:31:23 UTC (rev 271920)
@@ -1,3 +1,34 @@
+2021-01-26 Devin Rousso <[email protected]>
+
+ Expose the value of `<meta name="theme-color" content="...">` as SPI
+ https://bugs.webkit.org/show_bug.cgi?id=220944
+ <rdar://problem/72198083>
+
+ Reviewed by Tim Horton.
+
+ * html/HTMLMetaElement.h:
+ * html/HTMLMetaElement.cpp:
+ (WebCore::HTMLMetaElement::attributeChanged): Added.
+ (WebCore::HTMLMetaElement::parseAttribute):
+ (WebCore::HTMLMetaElement::removedFromAncestor): Added.
+ (WebCore::HTMLMetaElement::process):
+
+ * dom/Document.h:
+ (WebCore::Document::themeColor const): Added.
+ * dom/Document.cpp:
+ (WebCore::Document::processThemeColor): Added.
+ * page/Page.h:
+ * page/Page.cpp:
+ (WebCore::Page::themeColor const): Added.
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::themeColorChanged const): Added.
+ Save the `Color` to a variable so it can be accessed later during rendering so that updates
+ are kept in sync with other changes (e.g. modifying the CSS `background-color`).
+
+ * platform/graphics/cocoa/ColorCocoa.h:
+ * WebCore.xcodeproj/project.pbxproj:
+ Expose this file and export its functions so they can be used in WebKit.
+
2021-01-26 Simon Fraser <[email protected]>
Make showRenderTree() dump FloatingObjects
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (271919 => 271920)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-01-27 00:31:23 UTC (rev 271920)
@@ -5271,7 +5271,7 @@
F48223131E386E240066FC79 /* AbstractPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F48223121E386E240066FC79 /* AbstractPasteboard.h */; settings = {ATTRIBUTES = (Private, ); }; };
F48D2A6C215623B400C6752B /* FontShadow.h in Headers */ = {isa = PBXBuildFile; fileRef = F48D2A6A215623B400C6752B /* FontShadow.h */; settings = {ATTRIBUTES = (Private, ); }; };
F48D2A7E2157182600C6752B /* FontAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = F48D2A712156DC0A00C6752B /* FontAttributes.h */; settings = {ATTRIBUTES = (Private, ); }; };
- F48D2AA52159740D00C6752B /* ColorCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = F48D2AA32159740D00C6752B /* ColorCocoa.h */; };
+ F48D2AA52159740D00C6752B /* ColorCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = F48D2AA32159740D00C6752B /* ColorCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
F49786881FF45FA500E060AB /* PasteboardItemInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F49786871FF45FA500E060AB /* PasteboardItemInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
F4B422C4220C0568009E1E7D /* DOMPasteAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = F4B422C2220C0000009E1E7D /* DOMPasteAccess.h */; settings = {ATTRIBUTES = (Private, ); }; };
F4BFB9851E1DDF9B00862C24 /* DumpEditingHistory.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389831E1DDF2B0076B7EA /* DumpEditingHistory.js */; };
Modified: trunk/Source/WebCore/dom/Document.cpp (271919 => 271920)
--- trunk/Source/WebCore/dom/Document.cpp 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/dom/Document.cpp 2021-01-27 00:31:23 UTC (rev 271920)
@@ -33,6 +33,7 @@
#include "BeforeUnloadEvent.h"
#include "CDATASection.h"
#include "CSSFontSelector.h"
+#include "CSSParser.h"
#include "CSSStyleDeclaration.h"
#include "CSSStyleSheet.h"
#include "CachedCSSStyleSheet.h"
@@ -3797,6 +3798,20 @@
}
}
+void Document::processThemeColor(const String& themeColorString)
+{
+ auto themeColor = CSSParser::parseColor(themeColorString);
+ if (themeColor == m_themeColor)
+ return;
+
+ m_themeColor = WTFMove(themeColor);
+
+ scheduleRenderingUpdate({ });
+
+ if (auto* page = this->page())
+ page->chrome().client().themeColorChanged(m_themeColor);
+}
+
#if ENABLE(DARK_MODE_CSS)
static void processColorSchemeString(StringView colorScheme, const WTF::Function<void(StringView key)>& callback)
{
Modified: trunk/Source/WebCore/dom/Document.h (271919 => 271920)
--- trunk/Source/WebCore/dom/Document.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/dom/Document.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -739,6 +739,9 @@
#if !LOG_DISABLED
Seconds timeSinceDocumentCreation() const { return MonotonicTime::now() - m_documentCreationTime; };
#endif
+
+ const Color& themeColor() const { return m_themeColor; }
+
void setTextColor(const Color& color) { m_textColor = color; }
const Color& textColor() const { return m_textColor; }
@@ -908,6 +911,7 @@
void processDisabledAdaptations(const String& adaptations);
void updateViewportArguments();
void processReferrerPolicy(const String& policy, ReferrerPolicySource);
+ void processThemeColor(const String& themeColor);
#if ENABLE(DARK_MODE_CSS)
void processColorScheme(const String& colorScheme);
@@ -1776,6 +1780,7 @@
std::unique_ptr<FormController> m_formController;
+ Color m_themeColor;
Color m_textColor { Color::black };
Color m_linkColor;
Color m_visitedLinkColor;
Modified: trunk/Source/WebCore/html/HTMLMetaElement.cpp (271919 => 271920)
--- trunk/Source/WebCore/html/HTMLMetaElement.cpp 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/html/HTMLMetaElement.cpp 2021-01-27 00:31:23 UTC (rev 271920)
@@ -52,6 +52,14 @@
return adoptRef(*new HTMLMetaElement(tagName, document));
}
+void HTMLMetaElement::attributeChanged(const QualifiedName& name, const AtomString& oldValue, const AtomString& newValue, AttributeModificationReason reason)
+{
+ HTMLElement::attributeChanged(name, oldValue, newValue, reason);
+
+ if (name == nameAttr && equalLettersIgnoringASCIICase(oldValue, "theme-color") && !equalLettersIgnoringASCIICase(newValue, "theme-color"))
+ document().processThemeColor(emptyString());
+}
+
void HTMLMetaElement::parseAttribute(const QualifiedName& name, const AtomString& value)
{
if (name == http_equivAttr)
@@ -58,9 +66,9 @@
process();
else if (name == contentAttr)
process();
- else if (name == nameAttr) {
- // Do nothing
- } else
+ else if (name == nameAttr)
+ process();
+ else
HTMLElement::parseAttribute(name, value);
}
@@ -77,6 +85,14 @@
process();
}
+void HTMLMetaElement::removedFromAncestor(RemovalType removalType, ContainerNode& oldParentOfRemovedTree)
+{
+ HTMLElement::removedFromAncestor(removalType, oldParentOfRemovedTree);
+
+ if (!isConnected() && equalLettersIgnoringASCIICase(name(), "theme-color"))
+ oldParentOfRemovedTree.document().processThemeColor(emptyString());
+}
+
void HTMLMetaElement::process()
{
// Changing a meta tag while it's not in the tree shouldn't have any effect on the document.
@@ -95,6 +111,8 @@
else if (equalLettersIgnoringASCIICase(name(), "color-scheme") || equalLettersIgnoringASCIICase(name(), "supported-color-schemes"))
document().processColorScheme(contentValue);
#endif
+ else if (equalLettersIgnoringASCIICase(name(), "theme-color"))
+ document().processThemeColor(contentValue);
#if PLATFORM(IOS_FAMILY)
else if (equalLettersIgnoringASCIICase(name(), "format-detection"))
document().processFormatDetection(contentValue);
Modified: trunk/Source/WebCore/html/HTMLMetaElement.h (271919 => 271920)
--- trunk/Source/WebCore/html/HTMLMetaElement.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/html/HTMLMetaElement.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -39,9 +39,11 @@
private:
HTMLMetaElement(const QualifiedName&, Document&);
+ void attributeChanged(const QualifiedName&, const AtomString& oldValue, const AtomString& newValue, AttributeModificationReason = ModifiedDirectly) final;
void parseAttribute(const QualifiedName&, const AtomString&) final;
InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) final;
void didFinishInsertingNode();
+ void removedFromAncestor(RemovalType, ContainerNode&) final;
void process();
};
Modified: trunk/Source/WebCore/page/ChromeClient.h (271919 => 271920)
--- trunk/Source/WebCore/page/ChromeClient.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/page/ChromeClient.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -226,6 +226,7 @@
virtual Color underlayColor() const { return Color(); }
+ virtual void themeColorChanged(Color) const { }
virtual void pageExtendedBackgroundColorDidChange(Color) const { }
virtual void exceededDatabaseQuota(Frame&, const String& databaseName, DatabaseDetails) = 0;
Modified: trunk/Source/WebCore/page/Page.cpp (271919 => 271920)
--- trunk/Source/WebCore/page/Page.cpp 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/page/Page.cpp 2021-01-27 00:31:23 UTC (rev 271920)
@@ -2430,6 +2430,15 @@
m_requestedLayoutMilestones.remove(milestones);
}
+Color Page::themeColor() const
+{
+ auto* document = mainFrame().document();
+ if (!document)
+ return { };
+
+ return document->themeColor();
+}
+
Color Page::pageExtendedBackgroundColor() const
{
FrameView* frameView = mainFrame().view();
Modified: trunk/Source/WebCore/page/Page.h (271919 => 271920)
--- trunk/Source/WebCore/page/Page.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/page/Page.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -610,6 +610,7 @@
int headerHeight() const { return m_headerHeight; }
int footerHeight() const { return m_footerHeight; }
+ WEBCORE_EXPORT Color themeColor() const;
WEBCORE_EXPORT Color pageExtendedBackgroundColor() const;
bool isCountingRelevantRepaintedObjects() const;
Modified: trunk/Source/WebCore/platform/graphics/cocoa/ColorCocoa.h (271919 => 271920)
--- trunk/Source/WebCore/platform/graphics/cocoa/ColorCocoa.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebCore/platform/graphics/cocoa/ColorCocoa.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -33,11 +33,11 @@
class Color;
#if USE(APPKIT)
-NSColor *platformColor(const Color&);
+WEBCORE_EXPORT NSColor *platformColor(const Color&);
#endif
#if PLATFORM(IOS_FAMILY)
-UIColor *platformColor(const Color&);
+WEBCORE_EXPORT UIColor *platformColor(const Color&);
#endif
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (271919 => 271920)
--- trunk/Source/WebKit/ChangeLog 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/ChangeLog 2021-01-27 00:31:23 UTC (rev 271920)
@@ -1,3 +1,55 @@
+2021-01-26 Devin Rousso <[email protected]>
+
+ Expose the value of `<meta name="theme-color" content="...">` as SPI
+ https://bugs.webkit.org/show_bug.cgi?id=220944
+ <rdar://problem/72198083>
+
+ Reviewed by Tim Horton.
+
+ * WebProcess/WebPage/WebPage.h:
+ (WebKit::WebPage::themeColorChanged): Added.
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::willCommitLayerTree):
+ (WebKit::WebPage::didCommitLoad):
+ (WebKit::WebPage::flushPendingThemeColorChange): Added.
+ * WebProcess/WebCoreSupport/WebChromeClient.h:
+ * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+ (WebKit::WebChromeClient::themeColorChanged const):
+ * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
+ (WebKit::TiledCoreAnimationDrawingArea::updateRendering):
+ * UIProcess/WebPageProxy.messages.in:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::themeColorChanged): Added.
+ On macOS, keep a flag indicating whether the `themeColor` has changed. Use this flag when
+ updating rendering to send the `Color` to the UIProcess so that it's kept in sync with other
+ changes (e.g. modifying the CSS `background-color`).
+
+ * Shared/RemoteLayerTree/RemoteLayerTreeTransaction.h:
+ (WebKit::RemoteLayerTreeTransaction::themeColor const): Added.
+ (WebKit::RemoteLayerTreeTransaction::setThemeColor): Added.
+ * Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm:
+ (WebKit::RemoteLayerTreeTransaction::encode const):
+ (WebKit::RemoteLayerTreeTransaction::decode):
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::didCommitLayerTree):
+ On iOS, include the `themeColor` in every `RemoteLayerTreeTransaction` so that it's kept in
+ sync with other changes (e.g. modifying the CSS `background-color`).
+
+ * UIProcess/PageClient.h:
+ (WebKit::PageClient::themeColorWillChange): Added.
+ (WebKit::PageClient::themeColorDidChange): Added.
+ * UIProcess/Cocoa/PageClientImplCocoa.h:
+ * UIProcess/Cocoa/PageClientImplCocoa.mm:
+ (WebKit::PageClientImplCocoa::themeColorWillChange): Added.
+ (WebKit::PageClientImplCocoa::themeColorDidChange): Added.
+ Add support for ObjC KVO of `-[WKWebView _themeColor]`.
+
+ * UIProcess/WebPageProxy.h:
+ (WebKit::WebPageProxy::themeColor const): Added.
+ * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _themeColor]): Added.
+
2021-01-26 Brent Fulgham <[email protected]>
IPC::Decoder constructor should mark the Decoder as invalid if header decoding fails
Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.h (271919 => 271920)
--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -226,7 +226,10 @@
WebCore::LayoutPoint maxStableLayoutViewportOrigin() const { return m_maxStableLayoutViewportOrigin; }
void setMaxStableLayoutViewportOrigin(const WebCore::LayoutPoint& point) { m_maxStableLayoutViewportOrigin = point; };
-
+
+ WebCore::Color themeColor() const { return m_themeColor; }
+ void setThemeColor(WebCore::Color color) { m_themeColor = color; }
+
WebCore::Color pageExtendedBackgroundColor() const { return m_pageExtendedBackgroundColor; }
void setPageExtendedBackgroundColor(WebCore::Color color) { m_pageExtendedBackgroundColor = color; }
@@ -307,6 +310,7 @@
WebCore::LayoutPoint m_minStableLayoutViewportOrigin;
WebCore::LayoutPoint m_maxStableLayoutViewportOrigin;
WebCore::IntPoint m_scrollPosition;
+ WebCore::Color m_themeColor;
WebCore::Color m_pageExtendedBackgroundColor;
double m_pageScaleFactor { 1 };
double m_minimumScaleFactor { 1 };
Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm (271919 => 271920)
--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm 2021-01-27 00:31:23 UTC (rev 271920)
@@ -564,6 +564,7 @@
encoder << m_scrollPosition;
+ encoder << m_themeColor;
encoder << m_pageExtendedBackgroundColor;
encoder << m_pageScaleFactor;
encoder << m_minimumScaleFactor;
@@ -658,7 +659,10 @@
if (!decoder.decode(result.m_scrollPosition))
return false;
-
+
+ if (!decoder.decode(result.m_themeColor))
+ return false;
+
if (!decoder.decode(result.m_pageExtendedBackgroundColor))
return false;
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (271919 => 271920)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2021-01-27 00:31:23 UTC (rev 271920)
@@ -30,6 +30,7 @@
#import "APIFrameTreeNode.h"
#import "APIPageConfiguration.h"
#import "APISerializedScriptValue.h"
+#import "CocoaColor.h"
#import "CocoaImage.h"
#import "CompletionHandlerCallChecker.h"
#import "ContentAsStringIncludesChildFrames.h"
@@ -117,6 +118,7 @@
#import "_WKVisitedLinkStoreInternal.h"
#import "_WKWebsitePoliciesInternal.h"
#import <WebCore/AttributedString.h>
+#import <WebCore/ColorCocoa.h>
#import <WebCore/ColorSerialization.h>
#import <WebCore/ElementContext.h>
#import <WebCore/JSDOMBinding.h>
@@ -2786,6 +2788,14 @@
_page->setCanUseCredentialStorage(canUseCredentialStorage);
}
+- (CocoaColor *)_themeColor
+{
+ auto themeColor = _page->themeColor();
+ if (!themeColor.isValid())
+ return nil;
+ return WebCore::platformColor(themeColor);
+}
+
- (id <_WKInputDelegate>)_inputDelegate
{
return _inputDelegate.getAutoreleased();
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (271919 => 271920)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -362,6 +362,21 @@
- (void)_didEnableBrowserExtensions:(NSDictionary<NSString *, NSString *> *)extensionIDToNameMap WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
- (void)_didDisableBrowserExtensions:(NSSet<NSString *> *)extensionIDs WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+/*! @abstract The theme color of the active page.
+ @discussion This is the value of the most recently created or modified
+ @textblock
+ <meta name="theme-color" contents="...">
+ @/textblock
+ in the current page.
+ @link WKWebView @/link is key-value observing (KVO) compliant for this
+ property.
+ */
+#if TARGET_OS_IPHONE
+@property (nonatomic, readonly) UIColor *_themeColor WK_API_AVAILABLE(ios(WK_IOS_TBA));
+#else
+@property (nonatomic, readonly) NSColor *_themeColor WK_API_AVAILABLE(macos(WK_MAC_TBA));
+#endif
+
@end
#if TARGET_OS_IPHONE
Modified: trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h (271919 => 271920)
--- trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -49,6 +49,8 @@
void pageClosed() override;
+ void themeColorWillChange() final;
+ void themeColorDidChange() final;
void isPlayingAudioWillChange() final;
void isPlayingAudioDidChange() final;
Modified: trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm (271919 => 271920)
--- trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm 2021-01-27 00:31:23 UTC (rev 271920)
@@ -44,6 +44,16 @@
PageClientImplCocoa::~PageClientImplCocoa() = default;
+void PageClientImplCocoa::themeColorWillChange()
+{
+ [m_webView willChangeValueForKey:@"_themeColor"];
+}
+
+void PageClientImplCocoa::themeColorDidChange()
+{
+ [m_webView didChangeValueForKey:@"_themeColor"];
+}
+
void PageClientImplCocoa::isPlayingAudioWillChange()
{
[m_webView willChangeValueForKey:NSStringFromSelector(@selector(_isPlayingAudio))];
Modified: trunk/Source/WebKit/UIProcess/PageClient.h (271919 => 271920)
--- trunk/Source/WebKit/UIProcess/PageClient.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/UIProcess/PageClient.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -492,6 +492,8 @@
virtual void didFailNavigation(API::Navigation*) = 0;
virtual void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) = 0;
+ virtual void themeColorWillChange() { }
+ virtual void themeColorDidChange() { }
virtual void didChangeBackgroundColor() = 0;
virtual void isPlayingAudioWillChange() = 0;
virtual void isPlayingAudioDidChange() = 0;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (271919 => 271920)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-01-27 00:31:23 UTC (rev 271920)
@@ -8417,6 +8417,16 @@
m_pageCount = pageCount;
}
+void WebPageProxy::themeColorChanged(const Color& themeColor)
+{
+ if (m_themeColor == themeColor)
+ return;
+
+ pageClient().themeColorWillChange();
+ m_themeColor = themeColor;
+ pageClient().themeColorDidChange();
+}
+
void WebPageProxy::pageExtendedBackgroundColorDidChange(const Color& backgroundColor)
{
m_pageExtendedBackgroundColor = backgroundColor;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (271919 => 271920)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -629,6 +629,9 @@
float topContentInset() const { return m_topContentInset; }
void setTopContentInset(float);
+ // Corresponds to the web content's `<meta name="theme-color" content="...">`.
+ WebCore::Color themeColor() const { return m_themeColor; }
+
WebCore::Color underlayColor() const { return m_underlayColor; }
void setUnderlayColor(const WebCore::Color&);
@@ -1996,6 +1999,7 @@
void didChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar);
void didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide, bool pinnedToTopSide, bool pinnedToBottomSide);
void didChangePageCount(unsigned);
+ void themeColorChanged(const WebCore::Color&);
void pageExtendedBackgroundColorDidChange(const WebCore::Color&);
#if ENABLE(NETSCAPE_PLUGIN_API)
void didFailToInitializePlugin(const String& mimeType, const String& frameURLString, const String& pageURLString);
@@ -2541,6 +2545,7 @@
LayerHostingMode m_layerHostingMode { LayerHostingMode::InProcess };
+ WebCore::Color m_themeColor;
WebCore::Color m_underlayColor;
WebCore::Color m_pageExtendedBackgroundColor;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (271919 => 271920)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2021-01-27 00:31:23 UTC (rev 271920)
@@ -77,6 +77,7 @@
DidChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar)
DidChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide, bool pinnedToTopSide, bool pinnedToBottomSide)
DidChangePageCount(unsigned pageCount)
+ ThemeColorChanged(WebCore::Color themeColor)
PageExtendedBackgroundColorDidChange(WebCore::Color backgroundColor)
#if ENABLE(NETSCAPE_PLUGIN_API)
DidFailToInitializePlugin(String mimeType, String frameURLString, String pageURLString)
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (271919 => 271920)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2021-01-27 00:31:23 UTC (rev 271920)
@@ -335,6 +335,7 @@
void WebPageProxy::didCommitLayerTree(const WebKit::RemoteLayerTreeTransaction& layerTreeTransaction)
{
+ themeColorChanged(layerTreeTransaction.themeColor());
m_pageExtendedBackgroundColor = layerTreeTransaction.pageExtendedBackgroundColor();
if (!m_hasReceivedLayerTreeTransactionAfterDidCommitLoad) {
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (271919 => 271920)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp 2021-01-27 00:31:23 UTC (rev 271920)
@@ -1139,6 +1139,11 @@
return m_page.underlayColor();
}
+void WebChromeClient::themeColorChanged(Color /* themeColor */) const
+{
+ m_page.themeColorChanged();
+}
+
void WebChromeClient::pageExtendedBackgroundColorDidChange(Color backgroundColor) const
{
#if PLATFORM(MAC)
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (271919 => 271920)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -328,6 +328,7 @@
WebCore::Color underlayColor() const final;
+ void themeColorChanged(WebCore::Color) const final;
void pageExtendedBackgroundColorDidChange(WebCore::Color) const final;
void wheelEventHandlersChanged(bool) final;
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (271919 => 271920)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-01-27 00:31:23 UTC (rev 271920)
@@ -3908,6 +3908,7 @@
layerTransaction.setScrollOrigin(frameView->scrollOrigin());
layerTransaction.setPageScaleFactor(corePage()->pageScaleFactor());
layerTransaction.setRenderTreeSize(corePage()->renderTreeSize());
+ layerTransaction.setThemeColor(corePage()->themeColor());
layerTransaction.setPageExtendedBackgroundColor(corePage()->pageExtendedBackgroundColor());
layerTransaction.setBaseLayoutViewportSize(frameView->baseLayoutViewportSize());
@@ -3937,6 +3938,8 @@
layerTransaction.setScrollPosition(frameView->scrollPosition());
+ m_pendingThemeColorChange = false;
+
if (m_hasPendingEditorStateUpdate) {
layerTransaction.setEditorState(editorState());
m_hasPendingEditorStateUpdate = false;
@@ -6127,6 +6130,8 @@
m_loadCommitTime = WallTime::now();
#endif
+ themeColorChanged();
+
WebProcess::singleton().updateActivePages(m_processDisplayName);
updateMainFrameScrollOffsetPinning();
@@ -6264,6 +6269,16 @@
}
#endif
+void WebPage::flushPendingThemeColorChange()
+{
+ if (!m_pendingThemeColorChange)
+ return;
+
+ m_pendingThemeColorChange = false;
+
+ send(Messages::WebPageProxy::ThemeColorChanged(m_page->themeColor()));
+}
+
void WebPage::flushPendingEditorStateUpdate()
{
if (!m_hasPendingEditorStateUpdate)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (271919 => 271920)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2021-01-27 00:31:23 UTC (rev 271920)
@@ -1215,6 +1215,9 @@
static PluginView* pluginViewForFrame(WebCore::Frame*);
+ void themeColorChanged() { m_pendingThemeColorChange = true; }
+ void flushPendingThemeColorChange();
+
void flushPendingEditorStateUpdate();
#if ENABLE(RESOURCE_LOAD_STATISTICS)
@@ -2031,6 +2034,7 @@
RefPtr<WebCore::Element> m_focusedElement;
RefPtr<WebCore::Element> m_recentlyBlurredElement;
bool m_hasPendingInputContextUpdateAfterBlurringAndRefocusingElement { false };
+ bool m_pendingThemeColorChange { false };
bool m_hasPendingEditorStateUpdate { false };
#if ENABLE(IOS_TOUCH_EVENTS)
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm (271919 => 271920)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm 2021-01-27 00:31:23 UTC (rev 271920)
@@ -446,6 +446,7 @@
scaleViewToFitDocumentIfNeeded();
m_webPage.updateRendering();
+ m_webPage.flushPendingThemeColorChange();
m_webPage.flushPendingEditorStateUpdate();
m_webPage.flushPendingIntrinsicContentSizeUpdate();
Modified: trunk/Tools/ChangeLog (271919 => 271920)
--- trunk/Tools/ChangeLog 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Tools/ChangeLog 2021-01-27 00:31:23 UTC (rev 271920)
@@ -1,3 +1,20 @@
+2021-01-26 Devin Rousso <[email protected]>
+
+ Expose the value of `<meta name="theme-color" content="...">` as SPI
+ https://bugs.webkit.org/show_bug.cgi?id=220944
+ <rdar://problem/72198083>
+
+ Reviewed by Tim Horton.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm: Added.
+ (TEST.HTMLMetaThemeColor.OnLoad):
+ (TEST.HTMLMetaThemeColor.MultipleTags):
+ (-[WKWebViewThemeColorObserver initWithWebView:]):
+ (-[WKWebViewThemeColorObserver observeValueForKeyPath:ofObject:change:context:]):
+ (TEST.HTMLMetaThemeColor.KVO):
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+
2021-01-26 Lauro Moura <[email protected]>
[GLIB] API tests fail to report harness failures
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (271919 => 271920)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-01-27 00:11:09 UTC (rev 271919)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-01-27 00:31:23 UTC (rev 271920)
@@ -843,6 +843,7 @@
93F56DA91E5F919D003EDE84 /* WKWebViewSnapshot.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93F56DA81E5F9181003EDE84 /* WKWebViewSnapshot.mm */; };
93F7E86F14DC8E5C00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */; };
950E4CC1252E75240071659F /* iOSStylusSupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = 950E4CC0252E75230071659F /* iOSStylusSupport.mm */; };
+ 95A524952581A10D00461FE9 /* HTMLMetaThemeColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A524942581A10D00461FE9 /* HTMLMetaThemeColor.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 */; };
@@ -2484,6 +2485,7 @@
93F7E86B14DC8E4D00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames.cpp; sourceTree = "<group>"; };
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>"; };
+ 95A524942581A10D00461FE9 /* HTMLMetaThemeColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLMetaThemeColor.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>"; };
@@ -3316,6 +3318,7 @@
07E1F6A01FFC3A080096C7EC /* GetDisplayMedia.mm */,
2DADF26221CB8F32003D3E3A /* GetResourceData.mm */,
465E2806255B2A690063A787 /* GPUProcess.mm */,
+ 95A524942581A10D00461FE9 /* HTMLMetaThemeColor.mm */,
51AF23DE1EF1A3720072F281 /* IconLoadingDelegate.mm */,
EB230D3E245E726300C66AD1 /* IDBCheckpointWAL.mm */,
510477751D298E03009747EB /* IDBDeleteRecovery.mm */,
@@ -5300,6 +5303,7 @@
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 */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm (0 => 271920)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HTMLMetaThemeColor.mm 2021-01-27 00:31:23 UTC (rev 271920)
@@ -0,0 +1,169 @@
+/*
+ * 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/WKWebViewPrivate.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]);
+}