Changeset 282026 in webkit
- Timestamp:
- Sep 3, 2021 2:48:54 PM (11 months ago)
- Location:
- trunk
- Files:
-
- 16 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/applicationmanifest/multiple-links-expected.txt (modified) (1 diff)
-
LayoutTests/applicationmanifest/multiple-links.html (modified) (2 diffs)
-
LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-blocked.html (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/html/HTMLLinkElement.cpp (modified) (4 diffs)
-
Source/WebCore/html/HTMLLinkElement.h (modified) (1 diff)
-
Source/WebCore/loader/DocumentLoader.cpp (modified) (3 diffs)
-
Source/WebCore/loader/DocumentLoader.h (modified) (3 diffs)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (modified) (1 diff)
-
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h (modified) (1 diff)
-
Source/WebKit/WebProcess/WebPage/WebPage.cpp (modified) (3 diffs)
-
Source/WebKit/WebProcess/WebPage/WebPage.h (modified) (2 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r282025 r282026 1 2021-09-03 Devin Rousso <drousso@apple.com> 2 3 [Web App Manifest] Always fetch the first manifest if provided 4 https://bugs.webkit.org/show_bug.cgi?id=229059 5 <rdar://problem/82148333> 6 7 Reviewed by Brent Fulgham. 8 9 * applicationmanifest/multiple-links.html: 10 * applicationmanifest/multiple-links-expected.txt: 11 * http/tests/security/contentSecurityPolicy/manifest-src-blocked.html: 12 1 13 2021-09-03 Chris Dumez <cdumez@apple.com> 2 14 -
trunk/LayoutTests/applicationmanifest/multiple-links-expected.txt
r225598 r282026 1 urlscheme://2 - willSendRequest <NSURLRequest URL urlscheme://2, main document URL multiple-links.html, http method GET> redirectResponse (null) 1 2 multiple-links.html - didFinishLoading 2 urlscheme://1 - willSendRequest <NSURLRequest URL urlscheme://1, main document URL multiple-links.html, http method GET> redirectResponse (null) 3 urlscheme://1 - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -1002, failing URL "urlscheme://1"> 3 urlscheme://2 - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -1002, failing URL "urlscheme://2"> 4 4 -
trunk/LayoutTests/applicationmanifest/multiple-links.html
r225598 r282026 1 <link rel="manifest" href="urlscheme://1" media="print">2 <link rel="manifest" href="urlscheme://2">3 1 <script> 4 2 if (window.testRunner) { … … 6 4 testRunner.dumpAsText(); 7 5 testRunner.waitUntilDone(); 6 } 7 </script> 8 <link rel="manifest" href="urlscheme://1" media="print"> 9 <link rel="manifest" href="urlscheme://2"> 10 <script> 11 if (window.testRunner) { 8 12 testRunner.getApplicationManifestThen(function() { 9 13 testRunner.notifyDone(); -
trunk/LayoutTests/http/tests/security/contentSecurityPolicy/manifest-src-blocked.html
r225598 r282026 1 1 <meta http-equiv="Content-Security-Policy" content="manifest-src 'none'"> 2 <link rel="manifest" href="manifest.test/manifest.json">3 2 <script> 4 3 if (window.testRunner) { 5 4 testRunner.dumpAsText(); 6 5 testRunner.waitUntilDone(); 6 } 7 </script> 8 <link rel="manifest" href="manifest.test/manifest.json"> 9 <script> 10 if (window.testRunner) { 7 11 testRunner.getApplicationManifestThen(function() { 8 12 alert("Pass"); -
trunk/Source/WebCore/ChangeLog
r282022 r282026 1 2021-09-03 Devin Rousso <drousso@apple.com> 2 3 [Web App Manifest] Always fetch the first manifest if provided 4 https://bugs.webkit.org/show_bug.cgi?id=229059 5 <rdar://problem/82148333> 6 7 Reviewed by Brent Fulgham. 8 9 Before this patch, WebKit only fetched/parsed/applied/etc. the web app manifest when 10 `-[WKWebView _getApplicationManifestWithCompletionHandler:]` was called. This patch makes 11 WebKit do all that as soon as a `<link rel="manifest">` (with a valid URL) is encountered. 12 This allows manifests that have specified a `"theme_color"` to actually have an effect. 13 14 Tests: ApplicationManifest.AlwaysFetch 15 ApplicationManifest.OnlyFirstManifest 16 ApplicationManifest.NoManifest 17 ApplicationManifest.MediaAttriute 18 ApplicationManifest.DoesNotExist 19 ApplicationManifest.Blocked 20 21 * html/HTMLLinkElement.cpp: 22 (WebCore::HTMLLinkElement::process): 23 24 * loader/DocumentLoader.h: 25 * loader/DocumentLoader.cpp: 26 (WebCore::DocumentLoader::stopLoading): 27 (WebCore::DocumentLoader::loadApplicationManifest): 28 (WebCore::DocumentLoader::finishedLoadingApplicationManifest): 29 (WebCore::DocumentLoader::notifyFinishedLoadingApplicationManifest): Deleted. 30 Simplify the way that the UIProcess communicates with the WebProcess (and between WebKit and 31 WebCore). There's no need to have a `HashMap` of callbacks since each document can only have 32 at most one web app manifest. Furthermore, instead of having a `HashMap` in both WebKit and 33 WebCore, just pass along the `CompletionHandler` to the `DocumentLoader` for a single list 34 of completion callbacks (a list is needed because it's possible for a client to invoke 35 `-[WKWebView _getApplicationManifestWithCompletionHandler:]` multiple times). 36 1 37 2021-09-03 Tim Nguyen <ntim@apple.com> 2 38 -
trunk/Source/WebCore/html/HTMLLinkElement.cpp
r280479 r282026 36 36 #include "DefaultResourceLoadPriority.h" 37 37 #include "Document.h" 38 #include "DocumentLoader.h" 38 39 #include "Event.h" 39 40 #include "EventNames.h" … … 306 307 m_loading = true; 307 308 308 bool mediaQueryMatches = true;309 if (!m_media.isEmpty()) {310 std::optional<RenderStyle> documentStyle;311 if (document().hasLivingRenderTree())312 documentStyle = Style::resolveForDocument(document());313 auto media = MediaQuerySet::create(m_media, MediaQueryParserContext(document()));314 LOG(MediaQueries, "HTMLLinkElement::process evaluating queries");315 mediaQueryMatches = MediaQueryEvaluator { document().frame()->view()->mediaType(), document(), documentStyle ? &*documentStyle : nullptr }.evaluate(media.get());316 }317 318 309 // Don't hold up render tree construction and script execution on stylesheets 319 310 // that are not needed for the rendering at the moment. 320 bool isActive = media QueryMatches&& !isAlternate();311 bool isActive = mediaAttributeMatches() && !isAlternate(); 321 312 addPendingSheet(isActive ? ActiveSheet : InactiveSheet); 322 313 … … 352 343 notifyLoadedSheetAndAllCriticalSubresources(true); 353 344 } 354 } else if (m_sheet) { 345 346 return; 347 } 348 349 if (m_sheet) { 355 350 // we no longer contain a stylesheet, e.g. perhaps rel or type was changed 356 351 clearSheet(); 357 352 m_styleScope->didChangeActiveStyleSheetCandidates(); 358 } 353 return; 354 } 355 356 #if ENABLE(APPLICATION_MANIFEST) 357 if (isApplicationManifest()) { 358 if (RefPtr loader = document().loader()) 359 loader->loadApplicationManifest({ }); 360 return; 361 } 362 #endif // ENABLE(APPLICATION_MANIFEST) 359 363 } 360 364 … … 500 504 } 501 505 506 bool HTMLLinkElement::mediaAttributeMatches() const 507 { 508 if (m_media.isEmpty()) 509 return true; 510 511 std::optional<RenderStyle> documentStyle; 512 if (document().hasLivingRenderTree()) 513 documentStyle = Style::resolveForDocument(document()); 514 auto media = MediaQuerySet::create(m_media, MediaQueryParserContext(document())); 515 LOG(MediaQueries, "HTMLLinkElement::mediaAttributeMatches"); 516 return MediaQueryEvaluator(document().frame()->view()->mediaType(), document(), documentStyle ? &*documentStyle : nullptr).evaluate(media.get()); 517 } 518 502 519 void HTMLLinkElement::linkLoaded() 503 520 { -
trunk/Source/WebCore/html/HTMLLinkElement.h
r280479 r282026 65 65 bool isEnabledViaScript() const { return m_disabledState == EnabledViaScript; } 66 66 DOMTokenList& sizes(); 67 68 bool mediaAttributeMatches() const; 67 69 68 70 WEBCORE_EXPORT void setCrossOrigin(const AtomString&); -
trunk/Source/WebCore/loader/DocumentLoader.cpp
r281941 r282026 97 97 #include <wtf/NeverDestroyed.h> 98 98 #include <wtf/Ref.h> 99 #include <wtf/Scope.h> 99 100 #include <wtf/text/CString.h> 100 101 #include <wtf/text/WTFString.h> … … 333 334 334 335 #if ENABLE(APPLICATION_MANIFEST) 335 for (auto callbackIdentifier : m_applicationManifestLoaders.values())336 notifyFinishedLoadingApplicationManifest(callbackIdentifier, std::nullopt);337 m_applicationManifestLoaders.clear();336 m_applicationManifestLoader = nullptr; 337 m_finishedLoadingApplicationManifest = false; 338 notifyFinishedLoadingApplicationManifest(); 338 339 #endif 339 340 … … 1554 1555 1555 1556 #if ENABLE(APPLICATION_MANIFEST) 1556 uint64_t DocumentLoader::loadApplicationManifest() 1557 { 1558 static uint64_t nextCallbackID = 1; 1557 1558 void DocumentLoader::loadApplicationManifest(CompletionHandler<void(const std::optional<ApplicationManifest>&)>&& completionHandler) 1559 { 1560 if (completionHandler) 1561 m_loadApplicationManifestCallbacks.append(WTFMove(completionHandler)); 1562 1563 bool isLoading = !!m_applicationManifestLoader; 1564 auto notifyIfUnableToLoad = makeScopeExit([&] { 1565 if (!isLoading || m_finishedLoadingApplicationManifest) 1566 notifyFinishedLoadingApplicationManifest(); 1567 }); 1568 1569 if (isLoading) 1570 return; 1559 1571 1560 1572 auto* document = this->document(); 1561 1573 if (!document) 1562 return 0;1563 1564 if (! m_frame->isMainFrame())1565 return 0;1574 return; 1575 1576 if (!document->isTopDocument()) 1577 return; 1566 1578 1567 1579 if (document->url().isEmpty() || document->url().protocolIsAbout()) 1568 return 0;1580 return; 1569 1581 1570 1582 auto head = document->head(); 1571 1583 if (!head) 1572 return 0;1584 return; 1573 1585 1574 1586 URL manifestURL; 1575 1587 bool useCredentials = false; 1576 1588 for (const auto& link : childrenOfType<HTMLLinkElement>(*head)) { 1577 if (link.isApplicationManifest()) { 1578 manifestURL = link.href(); 1579 useCredentials = equalIgnoringASCIICase(link.attributeWithoutSynchronization(HTMLNames::crossoriginAttr), "use-credentials"); 1580 break; 1581 } 1589 if (!link.isApplicationManifest()) 1590 continue; 1591 1592 auto href = link.href(); 1593 if (href.isEmpty() || !href.isValid()) 1594 continue; 1595 1596 if (!link.mediaAttributeMatches()) 1597 continue; 1598 1599 manifestURL = href; 1600 useCredentials = equalIgnoringASCIICase(link.attributeWithoutSynchronization(HTMLNames::crossoriginAttr), "use-credentials"); 1601 break; 1582 1602 } 1583 1603 1584 1604 if (manifestURL.isEmpty() || !manifestURL.isValid()) 1585 return 0; 1586 1587 auto manifestLoader = makeUnique<ApplicationManifestLoader>(*this, manifestURL, useCredentials); 1588 auto* rawManifestLoader = manifestLoader.get(); 1589 auto callbackID = nextCallbackID++; 1590 m_applicationManifestLoaders.set(WTFMove(manifestLoader), callbackID); 1591 1592 if (!rawManifestLoader->startLoading()) { 1593 m_applicationManifestLoaders.remove(rawManifestLoader); 1594 return 0; 1595 } 1596 1597 return callbackID; 1605 return; 1606 1607 m_applicationManifestLoader = makeUnique<ApplicationManifestLoader>(*this, manifestURL, useCredentials); 1608 1609 isLoading = m_applicationManifestLoader->startLoading(); 1610 if (!isLoading) 1611 m_finishedLoadingApplicationManifest = true; 1598 1612 } 1599 1613 1600 1614 void DocumentLoader::finishedLoadingApplicationManifest(ApplicationManifestLoader& loader) 1601 1615 { 1616 ASSERT_UNUSED(loader, &loader == m_applicationManifestLoader.get()); 1617 1602 1618 // If the DocumentLoader has detached from its frame, all manifest loads should have already been canceled. 1603 1619 ASSERT(m_frame); 1604 1620 1605 auto callbackIdentifier = m_applicationManifestLoaders.get(&loader); 1606 notifyFinishedLoadingApplicationManifest(callbackIdentifier, loader.processManifest()); 1607 m_applicationManifestLoaders.remove(&loader); 1608 } 1609 1610 void DocumentLoader::notifyFinishedLoadingApplicationManifest(uint64_t callbackIdentifier, std::optional<ApplicationManifest> manifest) 1611 { 1612 RELEASE_ASSERT(callbackIdentifier); 1613 RELEASE_ASSERT(m_frame); 1614 m_frame->loader().client().finishedLoadingApplicationManifest(callbackIdentifier, manifest); 1615 } 1616 #endif 1621 ASSERT(!m_finishedLoadingApplicationManifest); 1622 m_finishedLoadingApplicationManifest = true; 1623 1624 notifyFinishedLoadingApplicationManifest(); 1625 } 1626 1627 void DocumentLoader::notifyFinishedLoadingApplicationManifest() 1628 { 1629 std::optional<ApplicationManifest> manifest = m_applicationManifestLoader ? m_applicationManifestLoader->processManifest() : std::nullopt; 1630 ASSERT_IMPLIES(manifest, m_finishedLoadingApplicationManifest); 1631 1632 for (auto& callback : std::exchange(m_loadApplicationManifestCallbacks, { })) 1633 callback(manifest); 1634 } 1635 1636 #endif // ENABLE(APPLICATION_MANIFEST) 1617 1637 1618 1638 bool DocumentLoader::isLoadingInAPISense() const -
trunk/Source/WebCore/loader/DocumentLoader.h
r281941 r282026 394 394 395 395 #if ENABLE(APPLICATION_MANIFEST) 396 WEBCORE_EXPORT uint64_t loadApplicationManifest();396 WEBCORE_EXPORT void loadApplicationManifest(CompletionHandler<void(const std::optional<ApplicationManifest>&)>&&); 397 397 void finishedLoadingApplicationManifest(ApplicationManifestLoader&); 398 398 #endif … … 517 517 518 518 #if ENABLE(APPLICATION_MANIFEST) 519 void notifyFinishedLoadingApplicationManifest( uint64_t callbackIdentifier, std::optional<ApplicationManifest>);519 void notifyFinishedLoadingApplicationManifest(); 520 520 #endif 521 521 … … 622 622 623 623 #if ENABLE(APPLICATION_MANIFEST) 624 HashMap<std::unique_ptr<ApplicationManifestLoader>, uint64_t> m_applicationManifestLoaders; 624 std::unique_ptr<ApplicationManifestLoader> m_applicationManifestLoader; 625 Vector<CompletionHandler<void(const std::optional<ApplicationManifest>&)>> m_loadApplicationManifestCallbacks; 626 bool m_finishedLoadingApplicationManifest { false }; 625 627 #endif 626 628 -
trunk/Source/WebKit/ChangeLog
r282013 r282026 1 2021-09-03 Devin Rousso <drousso@apple.com> 2 3 [Web App Manifest] Always fetch the first manifest if provided 4 https://bugs.webkit.org/show_bug.cgi?id=229059 5 <rdar://problem/82148333> 6 7 Reviewed by Brent Fulgham. 8 9 Before this patch, WebKit only fetched/parsed/applied/etc. the web app manifest when 10 `-[WKWebView _getApplicationManifestWithCompletionHandler:]` was called. This patch makes 11 WebKit do all that as soon as a `<link rel="manifest">` (with a valid URL) is encountered. 12 This allows manifests that have specified a `"theme_color"` to actually have an effect. 13 14 * WebProcess/WebCoreSupport/WebFrameLoaderClient.h: 15 * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: 16 (WebKit::WebFrameLoaderClient::finishedLoadingApplicationManifest): Deleted. 17 * WebProcess/WebPage/WebPage.h: 18 * WebProcess/WebPage/WebPage.cpp: 19 (WebKit::WebPage::~WebPage): 20 (WebKit::WebPage::getApplicationManifest): 21 (WebKit::WebPage::didFinishLoadingApplicationManifest): 22 Simplify the way that the UIProcess communicates with the WebProcess (and between WebKit and 23 WebCore). There's no need to have a `HashMap` of callbacks since each document can only have 24 at most one web app manifest. Furthermore, instead of having a `HashMap` in both WebKit and 25 WebCore, just pass along the `CompletionHandler` to the `DocumentLoader` for a single list 26 of completion callbacks (a list is needed because it's possible for a client to invoke 27 `-[WKWebView _getApplicationManifestWithCompletionHandler:]` multiple times). 28 1 29 2021-09-03 Per Arne <pvollan@apple.com> 2 30 -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
r281832 r282026 1934 1934 } 1935 1935 1936 #if ENABLE(APPLICATION_MANIFEST)1937 void WebFrameLoaderClient::finishedLoadingApplicationManifest(uint64_t callbackIdentifier, const std::optional<WebCore::ApplicationManifest>& manifest)1938 {1939 WebPage* webPage = m_frame->page();1940 if (!webPage)1941 return;1942 1943 webPage->didFinishLoadingApplicationManifest(callbackIdentifier, manifest);1944 }1945 #endif // ENABLE(APPLICATION_MANIFEST)1946 1947 1936 #if ENABLE(APP_BOUND_DOMAINS) 1948 1937 bool WebFrameLoaderClient::shouldEnableInAppBrowserPrivacyProtections() const -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h
r281832 r282026 271 271 void didCreateWindow(WebCore::DOMWindow&) final; 272 272 273 #if ENABLE(APPLICATION_MANIFEST)274 void finishedLoadingApplicationManifest(uint64_t, const std::optional<WebCore::ApplicationManifest>&) final;275 #endif276 277 273 Ref<WebFrame> m_frame; 278 274 RefPtr<PluginView> m_pluginView; -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r281980 r282026 1052 1052 for (auto& completionHandler : std::exchange(m_markLayersAsVolatileCompletionHandlers, { })) 1053 1053 completionHandler(false); 1054 1055 #if ENABLE(APPLICATION_MANIFEST)1056 for (auto& completionHandler : m_applicationManifestFetchCallbackMap.values()) {1057 if (completionHandler)1058 completionHandler(std::nullopt);1059 }1060 #endif1061 1054 } 1062 1055 … … 7209 7202 7210 7203 #if ENABLE(APPLICATION_MANIFEST) 7204 7211 7205 void WebPage::getApplicationManifest(CompletionHandler<void(const std::optional<WebCore::ApplicationManifest>&)>&& completionHandler) 7212 7206 { … … 7216 7210 return completionHandler(std::nullopt); 7217 7211 7218 auto coreCallbackID = loader->loadApplicationManifest(); 7219 if (!coreCallbackID) 7220 return completionHandler(std::nullopt); 7221 7222 m_applicationManifestFetchCallbackMap.add(coreCallbackID, WTFMove(completionHandler)); 7223 } 7224 7225 void WebPage::didFinishLoadingApplicationManifest(uint64_t coreCallbackID, const std::optional<WebCore::ApplicationManifest>& manifest) 7226 { 7227 if (auto callback = m_applicationManifestFetchCallbackMap.take(coreCallbackID)) 7228 callback(manifest); 7229 } 7212 loader->loadApplicationManifest(WTFMove(completionHandler)); 7213 } 7214 7230 7215 #endif // ENABLE(APPLICATION_MANIFEST) 7231 7216 -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
r281980 r282026 1297 1297 #if ENABLE(APPLICATION_MANIFEST) 1298 1298 void getApplicationManifest(CompletionHandler<void(const std::optional<WebCore::ApplicationManifest>&)>&&); 1299 void didFinishLoadingApplicationManifest(uint64_t, const std::optional<WebCore::ApplicationManifest>&);1300 1299 #endif 1301 1300 … … 2312 2311 HashMap<uint64_t, Function<void(bool granted)>> m_storageAccessResponseCallbackMap; 2313 2312 2314 #if ENABLE(APPLICATION_MANIFEST)2315 HashMap<uint64_t, CompletionHandler<void(const std::optional<WebCore::ApplicationManifest>&)>> m_applicationManifestFetchCallbackMap;2316 #endif2317 2318 2313 OptionSet<LayerTreeFreezeReason> m_layerTreeFreezeReasons; 2319 2314 bool m_isSuspended { false }; -
trunk/Tools/ChangeLog
r282025 r282026 1 2021-09-03 Devin Rousso <drousso@apple.com> 2 3 [Web App Manifest] Always fetch the first manifest if provided 4 https://bugs.webkit.org/show_bug.cgi?id=229059 5 <rdar://problem/82148333> 6 7 Reviewed by Brent Fulgham. 8 9 * TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm: 10 (TestWebKitAPI::TEST.ApplicationManifest.AlwaysFetch): Added. 11 (TestWebKitAPI::TEST.ApplicationManifest.OnlyFirstManifest): Added. 12 (TestWebKitAPI::TEST.ApplicationManifest.NoManifest): Added. 13 (TestWebKitAPI::TEST.ApplicationManifest.MediaAttriute): Added. 14 (TestWebKitAPI::TEST.ApplicationManifest.DoesNotExist): Added. 15 (TestWebKitAPI::TEST.ApplicationManifest.Blocked): Added. 16 1 17 2021-09-03 Chris Dumez <cdumez@apple.com> 2 18 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm
r276333 r282026 40 40 constexpr CGFloat redColorComponents[4] = { 1, 0, 0, 1 }; 41 41 42 TEST( WebKit, ApplicationManifestCoding)42 TEST(ApplicationManifest, Coding) 43 43 { 44 44 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\" }"; … … 61 61 } 62 62 63 TEST( WebKit, ApplicationManifestBasic)63 TEST(ApplicationManifest, Basic) 64 64 { 65 65 static bool done = false; … … 118 118 } 119 119 120 TEST( WebKit, ApplicationManifestDisplayMode)120 TEST(ApplicationManifest, DisplayMode) 121 121 { 122 122 static bool done; … … 150 150 } 151 151 152 TEST(ApplicationManifest, AlwaysFetch) 153 { 154 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect]); 155 156 NSDictionary *manifestObject = @{ @"theme_color": @"red" }; 157 [webView synchronouslyLoadHTMLString:[NSString stringWithFormat:@"<link rel=\"manifest\" href=\"data:application/manifest+json;charset=utf-8;base64,%@\">", [[NSJSONSerialization dataWithJSONObject:manifestObject options:0 error:nil] base64EncodedStringWithOptions:0]]]; 158 159 { 160 auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB)); 161 auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents)); 162 while (!CGColorEqualToColor([webView themeColor].CGColor, redColor.get())) 163 Util::sleep(1); 164 } 165 166 __block bool done = false; 167 [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) { 168 auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB)); 169 auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents)); 170 EXPECT_TRUE(CGColorEqualToColor(manifest.themeColor.CGColor, redColor.get())); 171 172 done = true; 173 }]; 174 Util::run(&done); 175 } 176 177 TEST(ApplicationManifest, OnlyFirstManifest) 178 { 179 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect]); 180 181 NSDictionary *manifestObject1 = @{ @"theme_color": @"red" }; 182 NSDictionary *manifestObject2 = @{ @"theme_color": @"blue" }; 183 [webView synchronouslyLoadHTMLString:[NSString stringWithFormat:@"<link rel=\"manifest\" href=\"data:application/manifest+json;charset=utf-8;base64,%@\"><link rel=\"manifest\" href=\"data:application/manifest+json;charset=utf-8;base64,%@\">", [[NSJSONSerialization dataWithJSONObject:manifestObject1 options:0 error:nil] base64EncodedStringWithOptions:0], [[NSJSONSerialization dataWithJSONObject:manifestObject2 options:0 error:nil] base64EncodedStringWithOptions:0]]]; 184 185 { 186 auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB)); 187 auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents)); 188 while (!CGColorEqualToColor([webView themeColor].CGColor, redColor.get())) 189 Util::sleep(1); 190 } 191 192 __block bool done = false; 193 [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) { 194 auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB)); 195 auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents)); 196 EXPECT_TRUE(CGColorEqualToColor(manifest.themeColor.CGColor, redColor.get())); 197 198 done = true; 199 }]; 200 Util::run(&done); 201 } 202 203 TEST(ApplicationManifest, NoManifest) 204 { 205 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect]); 206 207 [webView synchronouslyLoadHTMLString:@"Hello World"]; 208 209 EXPECT_NULL([webView themeColor]); 210 211 __block bool done = false; 212 [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) { 213 EXPECT_NULL(manifest); 214 215 done = true; 216 }]; 217 Util::run(&done); 218 } 219 220 TEST(ApplicationManifest, MediaAttriute) 221 { 222 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect]); 223 224 NSDictionary *manifestObject1 = @{ @"theme_color": @"blue" }; 225 NSDictionary *manifestObject2 = @{ @"theme_color": @"red" }; 226 [webView synchronouslyLoadHTMLString:[NSString stringWithFormat:@"<link rel=\"manifest\" href=\"data:application/manifest+json;charset=utf-8;base64,%@\" media=\"invalid\"><link rel=\"manifest\" href=\"data:application/manifest+json;charset=utf-8;base64,%@\" media=\"screen\">", [[NSJSONSerialization dataWithJSONObject:manifestObject1 options:0 error:nil] base64EncodedStringWithOptions:0], [[NSJSONSerialization dataWithJSONObject:manifestObject2 options:0 error:nil] base64EncodedStringWithOptions:0]]]; 227 228 { 229 auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB)); 230 auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents)); 231 while (!CGColorEqualToColor([webView themeColor].CGColor, redColor.get())) 232 Util::sleep(1); 233 } 234 235 __block bool done = false; 236 [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) { 237 auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB)); 238 auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents)); 239 EXPECT_TRUE(CGColorEqualToColor(manifest.themeColor.CGColor, redColor.get())); 240 241 done = true; 242 }]; 243 Util::run(&done); 244 } 245 246 TEST(ApplicationManifest, DoesNotExist) 247 { 248 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect]); 249 250 [webView synchronouslyLoadHTMLString:@"<link rel=\"manifest\" href=\"does not exist\">"]; 251 252 EXPECT_NULL([webView themeColor]); 253 254 __block bool done = false; 255 [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) { 256 EXPECT_NULL(manifest); 257 258 done = true; 259 }]; 260 Util::run(&done); 261 } 262 263 TEST(ApplicationManifest, Blocked) 264 { 265 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect]); 266 267 NSDictionary *manifestObject = @{ @"theme_color": @"red" }; 268 [webView synchronouslyLoadHTMLString:[NSString stringWithFormat:@"<meta http-equiv=\"Content-Security-Policy\" content=\"manifest-src 'none'\"><link rel=\"manifest\" href=\"data:application/manifest+json;charset=utf-8;base64,%@\">", [[NSJSONSerialization dataWithJSONObject:manifestObject options:0 error:nil] base64EncodedStringWithOptions:0]]]; 269 270 EXPECT_NULL([webView themeColor]); 271 272 __block bool done = false; 273 [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) { 274 EXPECT_NULL(manifest); 275 276 done = true; 277 }]; 278 Util::run(&done); 279 } 280 152 281 } // namespace TestWebKitAPI 153 282
Note: See TracChangeset
for help on using the changeset viewer.