Diff
Modified: trunk/Source/WebCore/ChangeLog (287403 => 287404)
--- trunk/Source/WebCore/ChangeLog 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Source/WebCore/ChangeLog 2021-12-23 17:57:29 UTC (rev 287404)
@@ -1,3 +1,39 @@
+2021-12-23 Wenson Hsieh <[email protected]>
+
+ Add API testing support for modal container observation
+ https://bugs.webkit.org/show_bug.cgi?id=234610
+
+ Reviewed by Megan Gardner.
+
+ Add support for new API tests for modal container observation SPI. See Tools/ChangeLog for more details.
+
+ Tests: ModalContainerObservation.HideAndAllowModalContainer
+ ModalContainerObservation.HideAndDisallowModalContainer
+ ModalContainerObservation.HideAndIgnoreModalContainer
+ ModalContainerObservation.ShowModalContainer
+
+ * dom/Document.h:
+ * page/ModalContainerObserver.cpp:
+ (WebCore::ModalContainerObserver::updateModalContainerIfNeeded):
+ (WebCore::ModalContainerObserver::shouldHide): Deleted.
+
+ Drive-by adjustment: make `shouldHide()` an inline method, and mark it `const`.
+
+ * page/ModalContainerObserver.h:
+ (WebCore::ModalContainerObserver::overrideSearchTermForTesting):
+
+ Add a testing-only method to override the search term used for modal container observation; if set, we ignore
+ the search term vended by the chrome client, and instead use this override.
+
+ (WebCore::ModalContainerObserver::shouldHide const):
+ * testing/Internals.cpp:
+ (WebCore::Internals::overrideModalContainerSearchTermForTesting):
+ * testing/Internals.h:
+
+ Add an `internals` hook to override the modal container search term.
+
+ * testing/Internals.idl:
+
2021-12-22 Simon Fraser <[email protected]>
Share macOS code between ScrollAnimator::handleWheelEvent() and ScrollingEffectsController::handleWheelEvent()
Modified: trunk/Source/WebCore/dom/Document.h (287403 => 287404)
--- trunk/Source/WebCore/dom/Document.h 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Source/WebCore/dom/Document.h 2021-12-23 17:57:29 UTC (rev 287404)
@@ -1663,7 +1663,7 @@
URL fallbackBaseURL() const;
- ModalContainerObserver* modalContainerObserver();
+ WEBCORE_EXPORT ModalContainerObserver* modalContainerObserver();
ModalContainerObserver* modalContainerObserverIfExists() const;
protected:
Modified: trunk/Source/WebCore/page/ModalContainerObserver.cpp (287403 => 287404)
--- trunk/Source/WebCore/page/ModalContainerObserver.cpp 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Source/WebCore/page/ModalContainerObserver.cpp 2021-12-23 17:57:29 UTC (rev 287404)
@@ -121,11 +121,16 @@
if (!view.hasViewportConstrainedObjects())
return;
- auto* page = view.frame().page();
- if (!page)
- return;
+ auto searchTerm = ([&]() -> AtomString {
+ if (UNLIKELY(!m_overrideSearchTermForTesting.isNull()))
+ return m_overrideSearchTermForTesting;
- auto& searchTerm = page->chrome().client().searchStringForModalContainerObserver();
+ if (auto* page = view.frame().page())
+ return page->chrome().client().searchStringForModalContainerObserver();
+
+ return nullAtom();
+ })();
+
if (searchTerm.isNull())
return;
@@ -436,9 +441,4 @@
return { WTFMove(classifiableControls), WTFMove(controlTextsToClassify) };
}
-bool ModalContainerObserver::shouldHide(const Element& element)
-{
- return &element == m_container && !m_collectingClickableElements;
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/page/ModalContainerObserver.h (287403 => 287404)
--- trunk/Source/WebCore/page/ModalContainerObserver.h 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Source/WebCore/page/ModalContainerObserver.h 2021-12-23 17:57:29 UTC (rev 287404)
@@ -30,6 +30,7 @@
#include <wtf/Vector.h>
#include <wtf/WeakHashSet.h>
#include <wtf/WeakPtr.h>
+#include <wtf/text/AtomString.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -47,9 +48,11 @@
ModalContainerObserver();
~ModalContainerObserver();
- bool shouldHide(const Element&);
+ inline bool shouldHide(const Element&) const;
void updateModalContainerIfNeeded(const FrameView&);
+ inline void overrideSearchTermForTesting(const String&);
+
private:
void scheduleClickableElementCollection();
void collectClickableElementsTimerFired();
@@ -59,9 +62,20 @@
WeakHashSet<Element> m_elementsToIgnoreWhenSearching;
WeakPtr<Element> m_container;
+ AtomString m_overrideSearchTermForTesting;
Timer m_collectClickableElementsTimer;
bool m_collectingClickableElements { false };
bool m_hasAttemptedToFulfillPolicy { false };
};
+inline void ModalContainerObserver::overrideSearchTermForTesting(const String& searchTerm)
+{
+ m_overrideSearchTermForTesting = searchTerm;
+}
+
+inline bool ModalContainerObserver::shouldHide(const Element& element) const
+{
+ return m_container == &element && !m_collectingClickableElements;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/testing/Internals.cpp (287403 => 287404)
--- trunk/Source/WebCore/testing/Internals.cpp 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Source/WebCore/testing/Internals.cpp 2021-12-23 17:57:29 UTC (rev 287404)
@@ -149,6 +149,7 @@
#include "MockLibWebRTCPeerConnection.h"
#include "MockPageOverlay.h"
#include "MockPageOverlayClient.h"
+#include "ModalContainerObserver.h"
#include "NavigatorBeacon.h"
#include "NavigatorMediaDevices.h"
#include "NetworkLoadInformation.h"
@@ -6624,4 +6625,10 @@
}
#endif
+void Internals::overrideModalContainerSearchTermForTesting(const String& term)
+{
+ if (auto observer = contextDocument()->modalContainerObserver())
+ observer->overrideSearchTermForTesting(term);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/testing/Internals.h (287403 => 287404)
--- trunk/Source/WebCore/testing/Internals.h 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Source/WebCore/testing/Internals.h 2021-12-23 17:57:29 UTC (rev 287404)
@@ -1228,6 +1228,8 @@
RefPtr<PushSubscription> createPushSubscription(const String& endpoint, std::optional<EpochTimeStamp> expirationTime, const ArrayBuffer& serverVAPIDPublicKey, const ArrayBuffer& clientECDHPublicKey, const ArrayBuffer& auth);
#endif
+ void overrideModalContainerSearchTermForTesting(const String& term);
+
private:
explicit Internals(Document&);
Document* contextDocument() const;
Modified: trunk/Source/WebCore/testing/Internals.idl (287403 => 287404)
--- trunk/Source/WebCore/testing/Internals.idl 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Source/WebCore/testing/Internals.idl 2021-12-23 17:57:29 UTC (rev 287404)
@@ -1097,4 +1097,6 @@
undefined retainTextIteratorForDocumentContent();
[Conditional=SERVICE_WORKER] PushSubscription createPushSubscription(USVString endpoint, EpochTimeStamp? expirationTime, ArrayBuffer serverVAPIDPublicKey, ArrayBuffer clientECDHPublicKey, ArrayBuffer auth);
+
+ undefined overrideModalContainerSearchTermForTesting(DOMString term);
};
Modified: trunk/Tools/ChangeLog (287403 => 287404)
--- trunk/Tools/ChangeLog 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Tools/ChangeLog 2021-12-23 17:57:29 UTC (rev 287404)
@@ -1,3 +1,57 @@
+2021-12-23 Wenson Hsieh <[email protected]>
+
+ Add API testing support for modal container observation
+ https://bugs.webkit.org/show_bug.cgi?id=234610
+
+ Reviewed by Megan Gardner.
+
+ Add support for new API tests that exercise the modal container observation policy in webpage preferences, as
+ well as the UI delegate SPI method for deciding policies in detected modal containers.
+
+ * TestWebKitAPI/SourcesCocoa.txt:
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKit/modal-container.html: Added.
+ * TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm:
+
+ Non-unified-source build fix (see below).
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm: Added.
+ (-[NSBundle swizzled_URLForResource:withExtension:]):
+ (TestWebKitAPI::ClassifierModelSwizzler::ClassifierModelSwizzler):
+ (TestWebKitAPI::ClassifierModelSwizzler::~ClassifierModelSwizzler):
+ (-[ModalContainerWebView initWithFrame:configuration:]):
+ (-[ModalContainerWebView loadBundlePage:andDecidePolicy:]):
+ (-[ModalContainerWebView _webView:decidePolicyForModalContainer:decisionHandler:]):
+ (TestWebKitAPI::createModalContainerWebView):
+ (TestWebKitAPI::TEST):
+
+ Add API tests to exercise each of the 4 modal container policy decisions in a simple modal container. Two key
+ pieces are needed in order to simulate the end-to-end flow for detecting and deciding policies for modal
+ containers:
+
+ 1. Add `internals.overrideModalContainerSearchTermForTesting()`, which allows script (through the
+ `internals` testing plugin) to set ModalContainerObserver's search term.
+
+ 2. Swizzle out `-[NSBundle URLForResource:withExtension:]` to return the file URL to TestWebKitAPI's
+ `TestModalContainerControls.mlmodelc`, instead of the real CoreML model.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/analytics/coremldata.bin: Added.
+ * TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/coremldata.bin: Copied from Source/WebCore/page/ModalContainerObserver.h.
+ * TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/metadata.json: Added.
+
+ Add a mock CoreML model that's used to simulate classifier results in WebKit::ModalContainerControlClassifier.
+ See above for more details.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewThemeColor.mm:
+ * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewUnderPageBackgroundColor.mm:
+ * TestWebKitAPI/Tests/WebKitCocoa/WebProcessTerminate.mm:
+
+ More non-unified-source build fixes: hoist the definitions of `redColorComponents` and `blueColorComponents`
+ into the `USE(CG)` part of TestCocoa.h, and then import TestCocoa.h in these files. This avoids build failures
+ due to symbol redefinition when we add the new test file above.
+
+ * TestWebKitAPI/cocoa/TestCocoa.h:
+
2021-12-23 Patrick Griffis <[email protected]>
[Flatpak] Fix a11y tests on some distros including Fedora
Modified: trunk/Tools/TestWebKitAPI/SourcesCocoa.txt (287403 => 287404)
--- trunk/Tools/TestWebKitAPI/SourcesCocoa.txt 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Tools/TestWebKitAPI/SourcesCocoa.txt 2021-12-23 17:57:29 UTC (rev 287404)
@@ -159,6 +159,7 @@
Tests/WebKitCocoa/MediaType.mm
Tests/WebKitCocoa/MessagePortProviders.mm
Tests/WebKitCocoa/ModalAlerts.mm
+Tests/WebKitCocoa/ModalContainerObservation.mm
Tests/WebKitCocoa/NSAttributedStringWebKitAdditions.mm
Tests/WebKitCocoa/NSFileManagerExtras.mm
Tests/WebKitCocoa/Navigation.mm
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (287403 => 287404)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-12-23 17:57:29 UTC (rev 287404)
@@ -1049,6 +1049,7 @@
F45D3891215A7B4B002A2979 /* TestInspectorBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45D3890215A7B4B002A2979 /* TestInspectorBar.mm */; };
F45E15732112CE2900307E82 /* KeyboardInputTestsIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45E15722112CE2900307E82 /* KeyboardInputTestsIOS.mm */; };
F45E15762112CE6200307E82 /* TestInputDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45E15752112CE6200307E82 /* TestInputDelegate.mm */; };
+ F45EB60427739F34003571AE /* TestModalContainerControls.mlmodelc in Copy Resources */ = {isa = PBXBuildFile; fileRef = F45EB60327739F2B003571AE /* TestModalContainerControls.mlmodelc */; };
F460F657261116EA0064F2B6 /* InjectedBundleHitTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = F460F656261116EA0064F2B6 /* InjectedBundleHitTest.mm */; };
F460F65B261119580064F2B6 /* InjectedBundleHitTestPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = F460F659261117E70064F2B6 /* InjectedBundleHitTestPlugIn.mm */; };
F460F669261263370064F2B6 /* simple-responsive-page.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F460F668261262C70064F2B6 /* simple-responsive-page.html */; };
@@ -1103,6 +1104,7 @@
F4E0A2B82122847400AF7C7F /* TestFilePromiseReceiver.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4E0A2B72122847400AF7C7F /* TestFilePromiseReceiver.mm */; };
F4E3D80820F70BB9007B58C5 /* significant-text-milestone-article.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E3D80720F708E4007B58C5 /* significant-text-milestone-article.html */; };
F4E7A66327222CA900E74D36 /* canvas-image-data.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E7A66227222BB100E74D36 /* canvas-image-data.html */; };
+ F4E86F8A2773DC1B003859A6 /* modal-container.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E86F892773DC06003859A6 /* modal-container.html */; };
F4EC8094260D30540010311D /* simple-image-overlay.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4EC8093260D2E620010311D /* simple-image-overlay.html */; };
F4F137921D9B683E002BEC57 /* large-video-test-now-playing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4F137911D9B6832002BEC57 /* large-video-test-now-playing.html */; };
F4F405BC1D4C0D1C007A9707 /* full-size-autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4F405BA1D4C0CF8007A9707 /* full-size-autoplaying-video-with-audio.html */; };
@@ -1472,6 +1474,7 @@
517E7E04151119C100D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html in Copy Resources */,
4971B1202453A88C0096994D /* missingTopFrameUniqueRedirectSameSiteStrictTableSchema.db in Copy Resources */,
51CD1C721B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html in Copy Resources */,
+ F4E86F8A2773DC1B003859A6 /* modal-container.html in Copy Resources */,
7A1458FC1AD5C07000E06772 /* mouse-button-listener.html in Copy Resources */,
33E79E06137B5FD900E32D99 /* mouse-move-listener.html in Copy Resources */,
9B59F12A2034086F009E63D5 /* mso-list-compat-mode.html in Copy Resources */,
@@ -1558,6 +1561,7 @@
524BBCA119E30C77002F1AF1 /* test.mp4 in Copy Resources */,
7AE9E5091AE5AE8B00CF874B /* test.pdf in Copy Resources */,
5C7101C725DD98B600686200 /* test_print.pdf in Copy Resources */,
+ F45EB60427739F34003571AE /* TestModalContainerControls.mlmodelc in Copy Resources */,
2E9896151D8F093800739892 /* text-and-password-inputs.html in Copy Resources */,
F4CD74C620FDACFA00DE3794 /* text-with-async-script.html in Copy Resources */,
F44C7A0520FAAE3C0014478C /* text-with-deferred-script.html in Copy Resources */,
@@ -3003,6 +3007,8 @@
F45E15722112CE2900307E82 /* KeyboardInputTestsIOS.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyboardInputTestsIOS.mm; sourceTree = "<group>"; };
F45E15742112CE6200307E82 /* TestInputDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestInputDelegate.h; sourceTree = "<group>"; };
F45E15752112CE6200307E82 /* TestInputDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestInputDelegate.mm; sourceTree = "<group>"; };
+ F45EB60327739F2B003571AE /* TestModalContainerControls.mlmodelc */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = TestModalContainerControls.mlmodelc; sourceTree = "<group>"; };
+ F45EB6062773C371003571AE /* ModalContainerObservation.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ModalContainerObservation.mm; sourceTree = "<group>"; };
F460F656261116EA0064F2B6 /* InjectedBundleHitTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundleHitTest.mm; sourceTree = "<group>"; };
F460F659261117E70064F2B6 /* InjectedBundleHitTestPlugIn.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundleHitTestPlugIn.mm; sourceTree = "<group>"; };
F460F65A2611183F0064F2B6 /* InjectedBundleHitTestProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InjectedBundleHitTestProtocol.h; sourceTree = "<group>"; };
@@ -3071,6 +3077,7 @@
F4E0A2B72122847400AF7C7F /* TestFilePromiseReceiver.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestFilePromiseReceiver.mm; sourceTree = "<group>"; };
F4E3D80720F708E4007B58C5 /* significant-text-milestone-article.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "significant-text-milestone-article.html"; sourceTree = "<group>"; };
F4E7A66227222BB100E74D36 /* canvas-image-data.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "canvas-image-data.html"; sourceTree = "<group>"; };
+ F4E86F892773DC06003859A6 /* modal-container.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "modal-container.html"; sourceTree = "<group>"; };
F4EB4E8F2328AC3000574DAB /* NSItemProviderAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NSItemProviderAdditions.h; path = cocoa/NSItemProviderAdditions.h; sourceTree = SOURCE_ROOT; };
F4EB4E902328AC3000574DAB /* NSItemProviderAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = NSItemProviderAdditions.mm; path = cocoa/NSItemProviderAdditions.mm; sourceTree = SOURCE_ROOT; };
F4EC8093260D2E620010311D /* simple-image-overlay.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-image-overlay.html"; sourceTree = "<group>"; };
@@ -3481,6 +3488,7 @@
51BE9E652376089500B4E117 /* MediaType.mm */,
5165FE03201EE617009F7EC3 /* MessagePortProviders.mm */,
51CD1C6A1B38CE3600142CA5 /* ModalAlerts.mm */,
+ F45EB6062773C371003571AE /* ModalContainerObservation.mm */,
1ABC3DED1899BE6D004F0626 /* Navigation.mm */,
6351992722275C6A00890AD3 /* NavigationAction.mm */,
5C8BC798218CF3E900813886 /* NetworkProcess.mm */,
@@ -4184,6 +4192,7 @@
31B76E4423299BA3007FED2C /* system-preview-trigger.html */,
313C3A0121E5677A00DBA86E /* SystemPreviewBlobNaming.html */,
F46D43AA26D7090300969E5E /* test.jpg */,
+ F45EB60327739F2B003571AE /* TestModalContainerControls.mlmodelc */,
2E9896141D8F092B00739892 /* text-and-password-inputs.html */,
F4CD74C520FDACF500DE3794 /* text-with-async-script.html */,
F44C7A0420FAAE320014478C /* text-with-deferred-script.html */,
@@ -4654,6 +4663,7 @@
CDC9442B1EF1FBD20059C3C4 /* mediastreamtrack-detached.html */,
4971B11F2453A87F0096994D /* missingTopFrameUniqueRedirectSameSiteStrictTableSchema.db */,
51CD1C711B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html */,
+ F4E86F892773DC06003859A6 /* modal-container.html */,
7A1458FB1AD5C03500E06772 /* mouse-button-listener.html */,
33E79E05137B5FCE00E32D99 /* mouse-move-listener.html */,
5797FE321EB15A8900B2F4A0 /* navigation-client-default-crypto.html */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKit/modal-container.html (0 => 287404)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit/modal-container.html (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/modal-container.html 2021-12-23 17:57:29 UTC (rev 287404)
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<style>
+body, html {
+ margin: 0;
+ background-color: #EFEFEF;
+ font-family: system-ui;
+}
+
+button {
+ padding: 6px;
+ border-radius: 6px;
+ appearance: none;
+ white-space: normal;
+ width: auto;
+ margin: 4px;
+ border: none;
+ font-size: 1em;
+ cursor: pointer;
+}
+
+#neutral {
+ color: rgb(88, 86, 214);
+ background-color: rgba(88, 86, 214, 0.1);
+}
+
+#negative {
+ color: rgb(255, 59, 48);
+ background-color: rgba(255, 59, 48, 0.1);
+}
+
+#positive {
+ color: rgb(76, 217, 100);
+ background-color: rgba(76, 217, 100, 0.1);
+}
+
+#fixed {
+ width: calc(min(300px, 80%));
+ bottom: 10px;
+ left: 10px;
+ position: fixed;
+ background-color: white;
+ border-radius: 8px;
+ padding: 16px;
+ box-shadow: 1px 1px 2px 2px #CCC;
+}
+
+#fixed > p {
+ font-size: 14px;
+}
+
+#fixed > h4 {
+ font-size: 16px;
+ margin-top: 6px;
+}
+
+#fixed-controls {
+ font-size: 16px;
+ margin-bottom: 1em;
+ text-align: center;
+}
+
+#result {
+ font-size: 16px;
+ font-weight: bold;
+ font-family: monospace;
+}
+</style>
+<script>
+if (window.internals)
+ internals.overrideModalContainerSearchTermForTesting("hello world");
+
+addEventListener("DOMContentLoaded", event => {
+ [negative, positive, neutral].forEach(control => {
+ control.addEventListener("click", () => {
+ fixed.remove();
+ result.textContent = `Clicked on "${control.textContent}"`;
+ });
+ });
+});
+</script>
+</head>
+<body>
+<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
+<div id="fixed">
+ <h4><span>This is a test</span></h4>
+ <p>Hello world</p>
+ <div class="fixed-controls">
+ <button id="positive">Yes</button>
+ <button id="negative">No</button>
+ <button id="neutral">Maybe</button>
+ </div>
+</div>
+<div id="result"><br></div>
+</body>
+</html>
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm (287403 => 287404)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm 2021-12-23 17:57:29 UTC (rev 287404)
@@ -29,6 +29,7 @@
#import "PlatformUtilities.h"
#import "Test.h"
+#import "TestCocoa.h"
#import "TestNavigationDelegate.h"
#import "TestWKWebView.h"
#import <WebCore/ApplicationManifest.h>
@@ -39,8 +40,6 @@
namespace TestWebKitAPI {
-constexpr CGFloat redColorComponents[4] = { 1, 0, 0, 1 };
-
TEST(ApplicationManifest, Coding)
{
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\" }";
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm (0 => 287404)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm 2021-12-23 17:57:29 UTC (rev 287404)
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2021 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 "PlatformUtilities.h"
+#import "TestProtocol.h"
+#import "TestWKWebView.h"
+#import "WKWebViewConfigurationExtras.h"
+#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKWebViewConfigurationPrivate.h>
+#import <WebKit/WKWebpagePreferencesPrivate.h>
+#import <objc/runtime.h>
+#import <wtf/CompletionHandler.h>
+#import <wtf/FastMalloc.h>
+#import <wtf/SetForScope.h>
+
+typedef _WKModalContainerDecision(^ModalContainerDecisionHandler)(_WKModalContainerInfo *);
+
+@interface NSBundle (TestSupport)
+- (NSURL *)swizzled_URLForResource:(NSString *)name withExtension:(NSString *)extension;
+@end
+
+@implementation NSBundle (TestSupport)
+
+- (NSURL *)swizzled_URLForResource:(NSString *)name withExtension:(NSString *)extension
+{
+ if ([name isEqualToString:@"ModalContainerControls"] && [extension isEqualToString:@"mlmodelc"]) {
+ // Override the default CoreML model with a smaller dataset that's limited to testing purposes.
+ return [NSBundle.mainBundle URLForResource:@"TestModalContainerControls" withExtension:@"mlmodelc" subdirectory:@"TestWebKitAPI.resources"];
+ }
+ // Call through to the original method implementation if we're not specifically requesting ModalContainerControls.mlmodelc.
+ return [self swizzled_URLForResource:name withExtension:extension];
+}
+
+@end
+
+namespace TestWebKitAPI {
+
+class ClassifierModelSwizzler {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ ClassifierModelSwizzler()
+ : m_originalMethod(class_getInstanceMethod(NSBundle.class, @selector(URLForResource:withExtension:)))
+ , m_swizzledMethod(class_getInstanceMethod(NSBundle.class, @selector(swizzled_URLForResource:withExtension:)))
+ {
+ m_originalImplementation = method_getImplementation(m_originalMethod);
+ m_swizzledImplementation = method_getImplementation(m_swizzledMethod);
+ class_replaceMethod(NSBundle.class, @selector(swizzled_URLForResource:withExtension:), m_originalImplementation, method_getTypeEncoding(m_originalMethod));
+ class_replaceMethod(NSBundle.class, @selector(URLForResource:withExtension:), m_swizzledImplementation, method_getTypeEncoding(m_swizzledMethod));
+ }
+
+ ~ClassifierModelSwizzler()
+ {
+ class_replaceMethod(NSBundle.class, @selector(swizzled_URLForResource:withExtension:), m_swizzledImplementation, method_getTypeEncoding(m_originalMethod));
+ class_replaceMethod(NSBundle.class, @selector(URLForResource:withExtension:), m_originalImplementation, method_getTypeEncoding(m_swizzledMethod));
+ }
+
+private:
+ Method m_originalMethod;
+ Method m_swizzledMethod;
+ IMP m_originalImplementation;
+ IMP m_swizzledImplementation;
+};
+
+} // namespace TestWebKitAPI
+
+@interface ModalContainerWebView : TestWKWebView <WKUIDelegatePrivate>
+@end
+
+@implementation ModalContainerWebView {
+ std::unique_ptr<TestWebKitAPI::ClassifierModelSwizzler> _classifierModelSwizzler;
+ RetainPtr<TestNavigationDelegate> _navigationDelegate;
+ std::optional<_WKModalContainerDecision> _decision;
+ bool _doneWaitingForDecisionHandler;
+}
+
+- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
+{
+ if (!(self = [super initWithFrame:frame configuration:configuration]))
+ return nil;
+
+ static std::once_flag onceFlag;
+ std::call_once(onceFlag, [] {
+ [TestProtocol registerWithScheme:@"http"];
+ });
+
+ _classifierModelSwizzler = makeUnique<TestWebKitAPI::ClassifierModelSwizzler>();
+ _navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
+ _doneWaitingForDecisionHandler = true;
+ [self setNavigationDelegate:_navigationDelegate.get()];
+ [self setUIDelegate:self];
+ return self;
+}
+
+- (void)loadBundlePage:(NSString *)page andDecidePolicy:(_WKModalContainerDecision)decision
+{
+ SetForScope decisionScope { _decision, decision };
+ _doneWaitingForDecisionHandler = false;
+
+ NSURL *bundleURL = [NSBundle.mainBundle URLForResource:page withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+ NSURLRequest *fakeRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://webkit.org"]];
+ [self loadSimulatedRequest:fakeRequest responseHTMLString:[NSString stringWithContentsOfURL:bundleURL]];
+
+ auto preferences = adoptNS([[WKWebpagePreferences alloc] init]);
+ [preferences _setModalContainerObservationPolicy:_WKWebsiteModalContainerObservationPolicyPrompt];
+ [_navigationDelegate waitForDidFinishNavigationWithPreferences:preferences.get()];
+
+ TestWebKitAPI::Util::run(&_doneWaitingForDecisionHandler);
+ [self waitForNextPresentationUpdate];
+}
+
+- (void)_webView:(WKWebView *)webView decidePolicyForModalContainer:(_WKModalContainerInfo *)containerInfo decisionHandler:(void (^)(_WKModalContainerDecision))handler
+{
+ handler(_decision.value_or(_WKModalContainerDecisionShow));
+ _doneWaitingForDecisionHandler = true;
+}
+
+@end
+
+namespace TestWebKitAPI {
+
+static RetainPtr<ModalContainerWebView> createModalContainerWebView()
+{
+ auto configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+ return adoptNS([[ModalContainerWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration]);
+}
+
+TEST(ModalContainerObservation, HideAndAllowModalContainer)
+{
+ auto webView = createModalContainerWebView();
+ [webView loadBundlePage:@"modal-container" andDecidePolicy:_WKModalContainerDecisionHideAndAllow];
+ NSString *visibleText = [webView contentsAsString];
+ EXPECT_TRUE([visibleText containsString:@"Clicked on \"Yes\""]);
+ EXPECT_FALSE([visibleText containsString:@"Hello world"]);
+}
+
+TEST(ModalContainerObservation, HideAndDisallowModalContainer)
+{
+ auto webView = createModalContainerWebView();
+ [webView loadBundlePage:@"modal-container" andDecidePolicy:_WKModalContainerDecisionHideAndDisallow];
+ NSString *visibleText = [webView contentsAsString];
+ EXPECT_TRUE([visibleText containsString:@"Clicked on \"No\""]);
+ EXPECT_FALSE([visibleText containsString:@"Hello world"]);
+}
+
+TEST(ModalContainerObservation, HideAndIgnoreModalContainer)
+{
+ auto webView = createModalContainerWebView();
+ [webView loadBundlePage:@"modal-container" andDecidePolicy:_WKModalContainerDecisionHideAndIgnore];
+ NSString *visibleText = [webView contentsAsString];
+ EXPECT_FALSE([visibleText containsString:@"Clicked on"]);
+ EXPECT_FALSE([visibleText containsString:@"Hello world"]);
+}
+
+TEST(ModalContainerObservation, ShowModalContainer)
+{
+ auto webView = createModalContainerWebView();
+ [webView loadBundlePage:@"modal-container" andDecidePolicy:_WKModalContainerDecisionShow];
+ NSString *visibleText = [webView contentsAsString];
+ EXPECT_FALSE([visibleText containsString:@"Clicked on"]);
+ EXPECT_TRUE([visibleText containsString:@"Hello world"]);
+}
+
+} // namespace TestWebKitAPI
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/analytics/coremldata.bin (0 => 287404)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/analytics/coremldata.bin (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/analytics/coremldata.bin 2021-12-23 17:57:29 UTC (rev 287404)
@@ -0,0 +1 @@
+��������������SpecificationDetails�������������� ��������������modelHash,��������������YXfJo7bzy9ftaGx0pQVlq2uhh5Rmnddw+sCIHcsI/MI= ��������������modelName��������������TestModalContainerControls
\ No newline at end of file
Copied: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/coremldata.bin (from rev 287403, trunk/Source/WebCore/page/ModalContainerObserver.h) (0 => 287404)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/coremldata.bin (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/coremldata.bin 2021-12-23 17:57:29 UTC (rev 287404)
@@ -0,0 +1,39 @@
+\xD0����������������������������������������������������������������spec��������������������������������������������������������������\xBC
+
+text
+Input text��R
+label
+Text label��\xA2\x87Wenson Hsieh"\xCA
+/*
+ * Copyright (C) 2021 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.
+ */\xA2%
+com.apple.createml.app.version3.0\xA25
+#com.apple.coreml.model.preview.typetextClassifier\xA2$
+com.apple.createml.version13.0.0\xA2"
+com.apple.createml.app.tag78.5\x82}\xB5\xA2\x88\xDE\xD3V ��������������4������v������\xB0������\xC8������x����!������\xA0����\x99������@����H������bplist00\xD3YModelType_NumberOfTrainingInstances]EmbeddingType��WDynamic5CEG��������������������������������������������������������O����$����?i\xD2"����>\xC1>����?i\xD2!����>\xC1>����?i\xD2 ����>\xC6\xD5U#����>\x92\x85����?E\xA7X'����>\x92\x85����>:[#����>\xB2$ ����?i\xD2����?i\xD2����?i\xD2����?i\xD2&����?i\xD2����>\xC6\xD5U����>\xC1>����?i\xD2����?i\xD2����?i\xD2%����?i\xD2����>\xB1v\x98����?*+����?i\xD2��negative��positive��neutral��other������������������������������������������������more��quite��not��correct��see��click��nah��yeah��so��possibly��nope��incorrect��yes��indeed��no��perhaps��here��read��info��out��maybe��yep��potentially��find����������������bplist00\xAF��
"��������������������������������������������������������$\xC2$
+negative
+positive
+neutral
+other
\ No newline at end of file
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/metadata.json (0 => 287404)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/metadata.json (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestModalContainerControls.mlmodelc/metadata.json 2021-12-23 17:57:29 UTC (rev 287404)
@@ -0,0 +1,54 @@
+[
+ {
+ "metadataOutputVersion" : "3.0",
+ "outputSchema" : [
+ {
+ "isOptional" : "0",
+ "formattedType" : "String",
+ "type" : "String",
+ "name" : "label",
+ "shortDescription" : "Text label"
+ }
+ ],
+ "modelParameters" : [
+
+ ],
+ "author" : "Wenson Hsieh",
+ "specificationVersion" : 3,
+ "license" : "\/*\n * Copyright (C) 2021 Apple Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and\/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS\n * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n *
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\/",
+ "isUpdatable" : "0",
+ "availability" : {
+ "macOS" : "10.14",
+ "tvOS" : "12.0",
+ "watchOS" : "5.0",
+ "iOS" : "12.0",
+ "macCatalyst" : "12.0"
+ },
+ "modelType" : {
+ "name" : "MLModelType_textClassifier"
+ },
+ "inputSchema" : [
+ {
+ "isOptional" : "0",
+ "formattedType" : "String",
+ "type" : "String",
+ "name" : "text",
+ "shortDescription" : "Input text"
+ }
+ ],
+ "classLabels" : [
+ "negative",
+ "positive",
+ "neutral",
+ "other"
+ ],
+ "generatedClassName" : "TestModalContainerControls",
+ "userDefinedMetadata" : {
+ "com.apple.createml.version" : "13.0.0",
+ "com.apple.createml.app.tag" : "78.5",
+ "com.apple.coreml.model.preview.type" : "textClassifier",
+ "com.apple.createml.app.version" : "3.0"
+ },
+ "method" : "predict"
+ }
+]
\ No newline at end of file
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewThemeColor.mm (287403 => 287404)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewThemeColor.mm 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewThemeColor.mm 2021-12-23 17:57:29 UTC (rev 287404)
@@ -38,9 +38,6 @@
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, MetaElementValidNameAndColor)
{
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewUnderPageBackgroundColor.mm (287403 => 287404)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewUnderPageBackgroundColor.mm 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewUnderPageBackgroundColor.mm 2021-12-23 17:57:29 UTC (rev 287404)
@@ -39,9 +39,6 @@
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 };
-
static RetainPtr<CGColor> defaultBackgroundColor()
{
#if HAVE(OS_DARK_MODE_SUPPORT) && PLATFORM(MAC)
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebProcessTerminate.mm (287403 => 287404)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebProcessTerminate.mm 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebProcessTerminate.mm 2021-12-23 17:57:29 UTC (rev 287404)
@@ -32,6 +32,7 @@
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/WebKit.h>
+#import <wtf/RetainPtr.h>
TEST(WebKit, WebProcessTerminate)
{
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestCocoa.h (287403 => 287404)
--- trunk/Tools/TestWebKitAPI/cocoa/TestCocoa.h 2021-12-23 17:55:01 UTC (rev 287403)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestCocoa.h 2021-12-23 17:57:29 UTC (rev 287404)
@@ -50,6 +50,9 @@
std::ostream& operator<<(std::ostream&, const CGRect&);
bool operator==(const CGRect&, const CGRect&);
+constexpr CGFloat redColorComponents[4] = { 1, 0, 0, 1 };
+constexpr CGFloat blueColorComponents[4] = { 0, 0, 1, 1 };
+
#endif
#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)