Diff
Modified: trunk/Source/WebCore/ChangeLog (286072 => 286073)
--- trunk/Source/WebCore/ChangeLog 2021-11-19 20:12:56 UTC (rev 286072)
+++ trunk/Source/WebCore/ChangeLog 2021-11-19 21:20:53 UTC (rev 286073)
@@ -1,3 +1,25 @@
+2021-11-19 Brent Fulgham <[email protected]>
+
+ Add support for web app manifest icons in WebKit/UI Process layer
+ https://bugs.webkit.org/show_bug.cgi?id=233350
+ <rdar://problem/84311569>
+
+ Reviewed by Chris Dumez.
+
+ This patch builds on the work in Bug 231339 and threads the new icons
+ feature through the WebKit layer.
+
+ This change modifies the parser to represent the 'sizes' member of the
+ icon as an array of strings, rather than a single string containing the
+ sizes as a set of space-separated items. This more closesly matches the
+ behavior of the WebKit API layer.
+
+ Tested by TestWebKitAPI.
+
+ * Modules/applicationmanifest/ApplicationManifest.h:
+ * Modules/applicationmanifest/ApplicationManifestParser.cpp:
+ (WebCore::ApplicationManifestParser::parseIcons):
+
2021-11-19 Antoine Quint <[email protected]>
[Model] add support for seeking animations
Modified: trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h (286072 => 286073)
--- trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h 2021-11-19 20:12:56 UTC (rev 286072)
+++ trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h 2021-11-19 21:20:53 UTC (rev 286073)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -50,7 +50,7 @@
};
URL src;
- String sizes;
+ Vector<String> sizes;
String type;
OptionSet<Purpose> purposes;
Modified: trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.cpp (286072 => 286073)
--- trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.cpp 2021-11-19 20:12:56 UTC (rev 286072)
+++ trunk/Source/WebCore/Modules/applicationmanifest/ApplicationManifestParser.cpp 2021-11-19 21:20:53 UTC (rev 286073)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -213,7 +213,7 @@
}
currentIcon.src = ""
- currentIcon.sizes = parseGenericString(iconJSON, "sizes"_s);
+ currentIcon.sizes = parseGenericString(iconJSON, "sizes"_s).split(' ');
currentIcon.type = parseGenericString(iconJSON, "type"_s);
Modified: trunk/Source/WebKit/ChangeLog (286072 => 286073)
--- trunk/Source/WebKit/ChangeLog 2021-11-19 20:12:56 UTC (rev 286072)
+++ trunk/Source/WebKit/ChangeLog 2021-11-19 21:20:53 UTC (rev 286073)
@@ -1,3 +1,31 @@
+2021-11-19 Brent Fulgham <[email protected]>
+
+ Add support for web app manifest icons in WebKit/UI Process layer
+ https://bugs.webkit.org/show_bug.cgi?id=233350
+ <rdar://problem/84311569>
+
+ Reviewed by Chris Dumez.
+
+ This patch builds on the work in Bug 231339 and threads the new icons
+ feature through the WebKit layer.
+
+ Note: This change also moves the implementation of _WKApplicationManifestIcon
+ earlier in the file since the implementation is needed for proper serialization
+ of the _WKApplicationManifest.
+
+ Tested by TestWebKitAPI (ApplicationManifest.Icons) test.
+
+ * UIProcess/API/Cocoa/_WKApplicationManifest.h:
+ * UIProcess/API/Cocoa/_WKApplicationManifest.mm:
+ (fromPurposes): New helper function.
+ (makeVectorElement): Ditto.
+ (-[_WKApplicationManifestIcon initWithCoder:]): Updated to call proper
+ serialization methods.
+ (-[_WKApplicationManifestIcon initWithCoreIcon:]): Added.
+ (-[_WKApplicationManifest initWithCoder:]): Updated to properly handle
+ serializing the object.
+ (-[_WKApplicationManifest icons]): Added.
+
2021-11-19 Per Arne <[email protected]>
[macOS] Enable message filtering for all WebKit processes
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.h (286072 => 286073)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.h 2021-11-19 20:12:56 UTC (rev 286072)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.h 2021-11-19 21:20:53 UTC (rev 286073)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -57,7 +57,7 @@
@property (nonatomic, readonly, nullable, copy) NSURL *scope;
@property (nonatomic, readonly, copy) NSURL *startURL;
@property (nonatomic, readonly) _WKApplicationManifestDisplayMode displayMode;
-@property (nonatomic, readonly) NSArray<_WKApplicationManifestIcon *> *icons WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic, readonly, copy) NSArray<_WKApplicationManifestIcon *> *icons WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
#if TARGET_OS_IPHONE
@property (nonatomic, readonly, nullable, copy) UIColor *themeColor WK_API_AVAILABLE(ios(15.0));
@@ -71,7 +71,12 @@
WK_CLASS_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA))
@interface _WKApplicationManifestIcon : NSObject <NSSecureCoding>
-// FIXME: https://bugs.webkit.org/show_bug.cgi?id=232959
+
+@property (nonatomic, readonly, copy) NSURL *src;
+@property (nonatomic, readonly, copy) NSArray<NSString *> *sizes;
+@property (nonatomic, readonly, copy) NSString *type;
+@property (nonatomic, readonly) NSArray<NSNumber *> *purposes;
+
@end
NS_ASSUME_NONNULL_END
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.mm (286072 => 286073)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.mm 2021-11-19 20:12:56 UTC (rev 286072)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKApplicationManifest.mm 2021-11-19 21:20:53 UTC (rev 286073)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -32,6 +32,7 @@
#import <WebCore/Color.h>
#import <WebCore/ColorCocoa.h>
#import <WebCore/WebCoreObjCExtras.h>
+#import <wtf/cocoa/VectorCocoa.h>
#if PLATFORM(IOS_FAMILY)
#import "UIKitSPI.h"
@@ -41,17 +42,103 @@
#import "AppKitSPI.h"
#endif
+static OptionSet<WebCore::ApplicationManifest::Icon::Purpose> fromPurposes(NSArray<NSNumber *> *purposes)
+{
+ OptionSet<WebCore::ApplicationManifest::Icon::Purpose> purposeSet;
+ for (NSNumber *purposeNumber in purposes) {
+ auto purpose = static_cast<WebCore::ApplicationManifest::Icon::Purpose>(purposeNumber.integerValue);
+ purposeSet.add(purpose);
+ }
+
+ return purposeSet;
+}
+
+static RetainPtr<NSArray<NSNumber *>> fromPurposes(OptionSet<WebCore::ApplicationManifest::Icon::Purpose> purposes)
+{
+ auto purposeArray = adoptNS([[NSMutableArray alloc] init]);
+ for (auto purpose : purposes)
+ [purposeArray addObject:[NSNumber numberWithUnsignedChar:static_cast<std::underlying_type<WebCore::ApplicationManifest::Icon::Purpose>::type>(purpose)]];
+ return purposeArray;
+}
+
static std::optional<WebCore::ApplicationManifest::Icon> makeVectorElement(const WebCore::ApplicationManifest::Icon*, id arrayElement)
{
-
if (![arrayElement isKindOfClass: _WKApplicationManifestIcon.class])
return std::nullopt;
+ auto icon = dynamic_objc_cast<_WKApplicationManifestIcon>(arrayElement);
+ if (!icon)
+ return std::nullopt;
+
return WebCore::ApplicationManifest::Icon {
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=232959
+ icon.src,
+ makeVector<String>(icon.sizes),
+ icon.type,
+ fromPurposes(icon.purposes)
};
}
+@implementation _WKApplicationManifestIcon
+
++ (BOOL)supportsSecureCoding
+{
+ return YES;
+}
+
+- (instancetype)initWithCoder:(NSCoder *)coder
+{
+ if (!(self = [self init]))
+ return nil;
+
+ _src = [[coder decodeObjectOfClass:[NSString class] forKey:@"src"] copy];
+ _sizes = [[coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSArray class], [NSString class]]] forKey:@"sizes"] copy];
+ _type = [[coder decodeObjectOfClass:[NSString class] forKey:@"type"] copy];
+ _purposes = [[coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSArray class], [NSString class]]] forKey:@"purposes"] copy];
+
+ return self;
+}
+
+- (instancetype)initWithCoreIcon:(const WebCore::ApplicationManifest::Icon *)icon
+{
+ if (!(self = [[_WKApplicationManifestIcon alloc] init]))
+ return nil;
+
+ if (icon) {
+ _src = [icon->src copy];
+ _sizes = createNSArray(icon->sizes, [] (auto& size) -> NSString * {
+ return size;
+ }).leakRef();
+ _type = [icon->type copy];
+ _purposes = fromPurposes(icon->purposes).leakRef();
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{
+ [coder encodeObject:_src forKey:@"src"];
+ [coder encodeObject:_sizes forKey:@"sizes"];
+ [coder encodeObject:_type forKey:@"type"];
+ [coder encodeObject:_purposes forKey:@"purposes"];
+}
+
+- (void)dealloc
+{
+ if (WebCoreObjCScheduleDeallocateOnMainRunLoop(_WKApplicationManifestIcon.class, self))
+ return;
+
+ [_src release];
+ [_sizes release];
+ [_type release];
+ [_purposes release];
+
+ [super dealloc];
+}
+
+@end
+
+
@implementation _WKApplicationManifest
#if ENABLE(APPLICATION_MANIFEST)
@@ -63,24 +150,24 @@
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
- NSString *name = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"name"];
- NSString *shortName = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"short_name"];
- NSString *description = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"description"];
- NSURL *scopeURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:@"scope"];
+ String name = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"name"];
+ String shortName = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"short_name"];
+ String description = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"description"];
+ URL scopeURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:@"scope"];
NSInteger display = [aDecoder decodeIntegerForKey:@"display"];
- NSURL *startURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:@"start_url"];
+ URL startURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:@"start_url"];
CocoaColor *themeColor = [aDecoder decodeObjectOfClass:[CocoaColor class] forKey:@"theme_color"];
NSArray<_WKApplicationManifestIcon *> *icons = [aDecoder decodeObjectOfClasses:[NSSet setWithArray:@[[NSArray class], [_WKApplicationManifestIcon class]]] forKey:@"icons"];
WebCore::ApplicationManifest coreApplicationManifest {
- WTF::String(name),
- WTF::String(shortName),
- WTF::String(description),
- URL(scopeURL),
+ WTFMove(name),
+ WTFMove(shortName),
+ WTFMove(description),
+ WTFMove(scopeURL),
static_cast<WebCore::ApplicationManifest::Display>(display),
- URL(startURL),
+ WTFMove(startURL),
WebCore::roundAndClampToSRGBALossy(themeColor.CGColor),
- Vector<WebCore::ApplicationManifest::Icon>(makeVector<WebCore::ApplicationManifest::Icon>(icons)),
+ makeVector<WebCore::ApplicationManifest::Icon>(icons),
};
API::Object::constructInWrapper<API::ApplicationManifest>(self, WTFMove(coreApplicationManifest));
@@ -174,8 +261,9 @@
- (NSArray<_WKApplicationManifestIcon *> *)icons
{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=232959
- return nil;
+ return createNSArray(_applicationManifest->applicationManifest().icons, [] (auto& coreIcon) -> id {
+ return adoptNS([[_WKApplicationManifestIcon alloc] initWithCoreIcon:&coreIcon]).autorelease();
+ }).autorelease();
}
#else // ENABLE(APPLICATION_MANIFEST)
@@ -243,34 +331,3 @@
#endif // ENABLE(APPLICATION_MANIFEST)
@end
-
-@implementation _WKApplicationManifestIcon
-
-+ (BOOL)supportsSecureCoding
-{
- return YES;
-}
-
-- (instancetype)initWithCoder:(NSCoder *)aDecoder
-{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=232959
- UNUSED_PARAM(aDecoder);
- [self release];
- return nil;
-}
-
-- (void)encodeWithCoder:(NSCoder *)aCoder
-{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=232959
- UNUSED_PARAM(aCoder);
-}
-
-- (void)dealloc
-{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=232959
- if (WebCoreObjCScheduleDeallocateOnMainRunLoop(_WKApplicationManifestIcon.class, self))
- return;
- [super dealloc];
-}
-
-@end
Modified: trunk/Tools/ChangeLog (286072 => 286073)
--- trunk/Tools/ChangeLog 2021-11-19 20:12:56 UTC (rev 286072)
+++ trunk/Tools/ChangeLog 2021-11-19 21:20:53 UTC (rev 286073)
@@ -1,3 +1,19 @@
+2021-11-19 Brent Fulgham <[email protected]>
+
+ Add support for web app manifest icons in WebKit/UI Process layer
+ https://bugs.webkit.org/show_bug.cgi?id=233350
+ <rdar://problem/84311569>
+
+ Reviewed by Chris Dumez.
+
+ Add a new API test to exercise the _WKApplicationManifestIcon API.
+
+ * TestWebKitAPI/Tests/WebCore/ApplicationManifestParser.cpp:
+ (ApplicationManifestParserTest::testIconsSizes):
+ (TEST_F):
+ * TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm:
+ (TestWebKitAPI::TEST):
+
2021-11-19 Robert Jenner <[email protected]>
[ Monterey ]TestWebKitAPI.PrivateClickMeasurement.EphemeralWithAttributedBundleIdentifier (API-test) is a constant timeout
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ApplicationManifestParser.cpp (286072 => 286073)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ApplicationManifestParser.cpp 2021-11-19 20:12:56 UTC (rev 286072)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ApplicationManifestParser.cpp 2021-11-19 21:20:53 UTC (rev 286073)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -160,11 +160,13 @@
EXPECT_STREQ(expectedValue.utf8().data(), value.utf8().data());
}
- void testIconsSizes(const String &rawJSON, const String& expectedValue)
+ void testIconsSizes(const String &rawJSON, size_t expectedCount, size_t testIndex, const String& expectedValue)
{
auto manifest = parseIconFirstTopLevelProperty("sizes", rawJSON);
auto value = manifest.icons[0].sizes;
- EXPECT_STREQ(expectedValue.utf8().data(), value.utf8().data());
+ EXPECT_EQ(expectedCount, value.size());
+ EXPECT_TRUE(testIndex < value.size());
+ EXPECT_STREQ(expectedValue.utf8().data(), value[testIndex].utf8().data());
}
void testIconsPurposes(const String &rawJSON, OptionSet<ApplicationManifest::Icon::Purpose> expectedValues)
@@ -368,8 +370,9 @@
URL srcURL = { { }, "https://example.com/icon.jpg" };
testIconsSrc("\"icon.jpg\"", srcURL);
testIconsType("\"image/webp\"", "image/webp");
- testIconsSizes("\"256x256\"", "256x256");
- testIconsSizes("\"72x72 96x96\"", "72x72 96x96");
+ testIconsSizes("\"256x256\"", 1, 0, "256x256");
+ testIconsSizes("\"72x72 96x96\"", 2, 0, "72x72");
+ testIconsSizes("\"72x72 96x96\"", 2, 1, "96x96");
OptionSet<ApplicationManifest::Icon::Purpose> purposeAny { ApplicationManifest::Icon::Purpose::Any };
OptionSet<ApplicationManifest::Icon::Purpose> purposeMonochrome { ApplicationManifest::Icon::Purpose::Monochrome };
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm (286072 => 286073)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm 2021-11-19 20:12:56 UTC (rev 286072)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplicationManifest.mm 2021-11-19 21:20:53 UTC (rev 286073)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -278,6 +278,89 @@
Util::run(&done);
}
+TEST(ApplicationManifest, Icons)
+{
+ static bool done = false;
+
+ NSArray *expectedIcons = @[ @{
+ @"src": @"https://example.com/images/touch/homescreen32.png",
+ @"sizes": @"32x32",
+ @"type": @"image/png"
+ }, @{
+ @"src": @"https://example.com/images/touch/homescreen48.png",
+ @"sizes": @"48x48",
+ @"type": @"image/png",
+ @"purpose": @"monochrome maskable"
+ }, @{
+ @"src": @"https://example.com/images/touch/homescreen128.jpg",
+ @"sizes": @"96x96 128x128",
+ @"type": @"image/jpg",
+ @"purpose": @"monochrome"
+ }];
+
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect]);
+ NSDictionary *manifestObject = @{
+ @"name": @"A Web Application",
+ @"short_name": @"WebApp",
+ @"description": @"Hello.",
+ @"start_url": @"http://example.com/app/start",
+ @"scope": @"http://example.com/app",
+ @"theme_color": @"red",
+ @"icons": expectedIcons
+ };
+ NSString *htmlString = [NSString stringWithFormat:@"<link rel=\"manifest\" href="" [[NSJSONSerialization dataWithJSONObject:manifestObject options:0 error:nil] base64EncodedStringWithOptions:0]];
+ [webView loadHTMLString:htmlString baseURL:[NSURL URLWithString:@"http://example.com/app/index"]];
+ [webView _test_waitForDidFinishNavigation];
+ [webView _getApplicationManifestWithCompletionHandler:^(_WKApplicationManifest *manifest) {
+ EXPECT_TRUE([manifest.name isEqualToString:@"A Web Application"]);
+ EXPECT_TRUE([manifest.shortName isEqualToString:@"WebApp"]);
+ EXPECT_TRUE([manifest.applicationDescription isEqualToString:@"Hello."]);
+ EXPECT_TRUE([manifest.startURL isEqual:[NSURL URLWithString:@"http://example.com/app/start"]]);
+ EXPECT_TRUE([manifest.scope isEqual:[NSURL URLWithString:@"http://example.com/app"]]);
+
+ auto sRGBColorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+ auto redColor = adoptCF(CGColorCreate(sRGBColorSpace.get(), redColorComponents));
+ EXPECT_TRUE(CGColorEqualToColor(manifest.themeColor.CGColor, redColor.get()));
+
+ size_t iconIndex = 0;
+ for (_WKApplicationManifestIcon *icon in manifest.icons) {
+ NSDictionary *expectedIcon = expectedIcons[iconIndex];
+ NSString *expectedURLString = [expectedIcon objectForKey:@"src"];
+ EXPECT_TRUE([icon.src isEqual:[NSURL URLWithString:expectedURLString]]);
+ EXPECT_TRUE([icon.type isEqual:[expectedIcon objectForKey:@"type"]]);
+
+ switch (iconIndex) {
+ case 0:
+ EXPECT_EQ(icon.sizes.count, 1ul);
+ EXPECT_TRUE([icon.sizes[0] isEqual:[expectedIcon objectForKey:@"sizes"]]);
+ EXPECT_EQ(icon.purposes.count, 1ul);
+ EXPECT_EQ(icon.purposes[0].unsignedLongValue, 1ul);
+ break;
+
+ case 1:
+ EXPECT_EQ(icon.sizes.count, 1ul);
+ EXPECT_TRUE([icon.sizes[0] isEqual:[expectedIcon objectForKey:@"sizes"]]);
+ EXPECT_EQ(icon.purposes.count, 2ul);
+ EXPECT_EQ(icon.purposes[0].unsignedLongValue, 2ul);
+ EXPECT_EQ(icon.purposes[1].unsignedLongValue, 4ul);
+ break;
+
+ case 2:
+ EXPECT_EQ(icon.sizes.count, 2ul);
+ EXPECT_TRUE([icon.sizes[0] isEqual:@"96x96"]);
+ EXPECT_TRUE([icon.sizes[1] isEqual:@"128x128"]);
+ EXPECT_EQ(icon.purposes.count, 1ul);
+ EXPECT_EQ(icon.purposes[0].unsignedLongValue, 2ul);
+ break;
+ }
+
+ ++iconIndex;
+ }
+ done = true;
+ }];
+ Util::run(&done);
+}
+
} // namespace TestWebKitAPI
#endif // ENABLE(APPLICATION_MANIFEST)