Skip to content
Permalink
Browse files
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.

Source/WebCore:

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):

Source/WebKit:

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.

Tools:

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):



Canonical link: https://commits.webkit.org/244460@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286073 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
brentfulgham committed Nov 19, 2021
1 parent acaf198 commit 8b3d621b2da4620757903dd4c4d67f36951ba7f6
Showing 9 changed files with 274 additions and 60 deletions.
@@ -1,3 +1,25 @@
2021-11-19 Brent Fulgham <bfulgham@apple.com>

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 <graouts@webkit.org>

[Model] add support for seeking animations
@@ -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 @@ struct ApplicationManifest {
};

URL src;
String sizes;
Vector<String> sizes;
String type;
OptionSet<Purpose> purposes;

@@ -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 @@ Vector<ApplicationManifest::Icon> ApplicationManifestParser::parseIcons(const JS
}
currentIcon.src = srcURL;

currentIcon.sizes = parseGenericString(iconJSON, "sizes"_s);
currentIcon.sizes = parseGenericString(iconJSON, "sizes"_s).split(' ');

currentIcon.type = parseGenericString(iconJSON, "type"_s);

@@ -1,3 +1,31 @@
2021-11-19 Brent Fulgham <bfulgham@apple.com>

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 <pvollan@apple.com>

[macOS] Enable message filtering for all WebKit processes
@@ -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 @@ WK_CLASS_AVAILABLE(macos(10.13.4), ios(11.3))
@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(10.13.4), ios(11.3))

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
@@ -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 std::optional<WebCore::ApplicationManifest::Icon> makeVectorElement(const WebCore::ApplicationManifest::Icon*, id arrayElement)
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 @@ + (BOOL)supportsSecureCoding

- (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 @@ - (_WKApplicationManifestDisplayMode)displayMode

- (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 @@ - (_WKApplicationManifestDisplayMode)displayMode
#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
@@ -1,3 +1,19 @@
2021-11-19 Brent Fulgham <bfulgham@apple.com>

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 <Jenner@apple.com>

[ Monterey ]TestWebKitAPI.PrivateClickMeasurement.EphemeralWithAttributedBundleIdentifier (API-test) is a constant timeout
@@ -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 @@ class ApplicationManifestParserTest : public testing::Test {
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 @@ TEST_F(ApplicationManifestParserTest, Icons)
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 };

0 comments on commit 8b3d621

Please sign in to comment.