Skip to content

Commit c63a695

Browse files
committed
REGRESSION (iOS 17): Dragging a calendar event from Spotlight into Mail doesn’t attach an .ics file
https://bugs.webkit.org/show_bug.cgi?id=272308 rdar://120436702 Reviewed by Abrar Protyasha. In iOS 17, Spotlight no longer sets `-[NSItemProvider suggestedName]` when dragging calendar events. This causes a drop from Spotlight into Mail compose to fall back to inserting plain text instead of a file, since: 1. The dropped item has a plain text representation. 2. The dropped item does not have a preferred attachment representation type specified. 3. The dropped item does not have a suggested file name specified. The fact that Spotlight has stopped vending this suggested name in iOS 17 is being tracked in rdar://126050147; in the meantime, we can also improve this experience in WebKit by treating dropped calendar invites as one of the types that defaults to being inserted as an attachment, rather than text (similar to PDF and VCard files). * Source/WebCore/platform/ios/PasteboardIOS.mm: (WebCore::shouldTreatAsAttachmentByDefault): * Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm: (TestWebKitAPI::calendarInviteForTesting): (TestWebKitAPI::TEST(WKAttachmentTestsIOS, InsertDroppedCalendarInviteAsAttachment)): * Tools/TestWebKitAPI/Tests/WebKitCocoa/event.ics: Added. Add an API test to verify the fix. Canonical link: https://commits.webkit.org/277187@main
1 parent 6f39fe0 commit c63a695

File tree

4 files changed

+72
-2
lines changed

4 files changed

+72
-2
lines changed

Source/WebCore/platform/ios/PasteboardIOS.mm

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,12 @@ static void readURLAlongsideAttachmentIfNecessary(PasteboardWebContentReader& re
305305

306306
static bool shouldTreatAsAttachmentByDefault(const String& typeIdentifier)
307307
{
308-
auto type = [UTType typeWithIdentifier:typeIdentifier];
309-
return [type conformsToType:UTTypeVCard] || [type conformsToType:UTTypePDF];
308+
RetainPtr type = [UTType typeWithIdentifier:typeIdentifier];
309+
for (UTType *attachmentType : std::array { UTTypeVCard, UTTypePDF, UTTypeCalendarEvent }) {
310+
if ([type conformsToType:attachmentType])
311+
return true;
312+
}
313+
return false;
310314
}
311315

312316
static bool prefersAttachmentRepresentation(const PasteboardItemInfo& info)

Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,7 @@
11451145
F407FE391F1D0DFC0017CF25 /* enormous.svg in Copy Resources */ = {isa = PBXBuildFile; fileRef = F407FE381F1D0DE60017CF25 /* enormous.svg */; };
11461146
F4094CC725545BD5003D73E3 /* DisplayListTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4094CC625545BD5003D73E3 /* DisplayListTests.cpp */; };
11471147
F40B8D5E281086E500346417 /* fade-in-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F40B8D5D2810855900346417 /* fade-in-image.html */; };
1148+
F41462BA2BC346B80027261C /* event.ics in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41462AA2BC346130027261C /* event.ics */; };
11481149
F415086D1DA040C50044BE9B /* play-audio-on-click.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F415086C1DA040C10044BE9B /* play-audio-on-click.html */; };
11491150
F418BE151F71B7DC001970E6 /* RoundedRectTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F418BE141F71B7DC001970E6 /* RoundedRectTests.cpp */; };
11501151
F4194AD11F5A320100ADD83F /* drop-targets.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4194AD01F5A2EA500ADD83F /* drop-targets.html */; };
@@ -1635,6 +1636,7 @@
16351636
F4C2AB221DD6D95E00E06D5B /* enormous-video-with-sound.html in Copy Resources */,
16361637
F407FE391F1D0DFC0017CF25 /* enormous.svg in Copy Resources */,
16371638
07492B3C1DF8B86600633DE1 /* enumerateMediaDevices.html in Copy Resources */,
1639+
F41462BA2BC346B80027261C /* event.ics in Copy Resources */,
16381640
C5E1AFFE16B221F1006CC1F2 /* execCopy.html in Copy Resources */,
16391641
7283A9D222FB1E0600B21C7D /* exif-orientation-8-llo.jpg in Copy Resources */,
16401642
CDA29B2B20FD358400F15CED /* ExitFullscreenOnEnterPiP.html in Copy Resources */,
@@ -3503,6 +3505,7 @@
35033505
F4094CC625545BD5003D73E3 /* DisplayListTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayListTests.cpp; sourceTree = "<group>"; };
35043506
F40B8D5D2810855900346417 /* fade-in-image.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "fade-in-image.html"; sourceTree = "<group>"; };
35053507
F4106C6821ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewFirstResponderTests.mm; sourceTree = "<group>"; };
3508+
F41462AA2BC346130027261C /* event.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = event.ics; sourceTree = "<group>"; };
35063509
F415086C1DA040C10044BE9B /* play-audio-on-click.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "play-audio-on-click.html"; sourceTree = "<group>"; };
35073510
F418BE141F71B7DC001970E6 /* RoundedRectTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RoundedRectTests.cpp; sourceTree = "<group>"; };
35083511
F4194AD01F5A2EA500ADD83F /* drop-targets.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "drop-targets.html"; sourceTree = "<group>"; };
@@ -4838,6 +4841,7 @@
48384841
51C8E1A81F27F47300BF731B /* EmptyGrandfatheredResourceLoadStatistics.plist */,
48394842
F4C2AB211DD6D94100E06D5B /* enormous-video-with-sound.html */,
48404843
F407FE381F1D0DE60017CF25 /* enormous.svg */,
4844+
F41462AA2BC346130027261C /* event.ics */,
48414845
7283A9D122FB1D9700B21C7D /* exif-orientation-8-llo.jpg */,
48424846
CDA29B2A20FD344E00F15CED /* ExitFullscreenOnEnterPiP.html */,
48434847
F40B8D5D2810855900346417 /* fade-in-image.html */,

Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,6 +2559,18 @@ static void _generateBestRepresentationForRequest(id, SEL)
25592559
return itemProvider;
25602560
}
25612561

2562+
static RetainPtr<NSItemProvider> calendarInviteForTesting()
2563+
{
2564+
RetainPtr url = [[NSBundle mainBundle] URLForResource:@"event" withExtension:@"ics" subdirectory:@"TestWebKitAPI.resources"];
2565+
RetainPtr data = [NSData dataWithContentsOfURL:url.get()];
2566+
RetainPtr text = adoptNS([[NSString alloc] initWithData:data.get() encoding:NSUTF8StringEncoding]);
2567+
RetainPtr itemProvider = adoptNS([[NSItemProvider alloc] init]);
2568+
[itemProvider registerData:data.get() type:@"com.apple.calendar.ics"];
2569+
[itemProvider registerData:data.get() type:@"com.apple.ical.ics"];
2570+
[itemProvider registerObject:text.get() visibility:NSItemProviderRepresentationVisibilityAll];
2571+
return itemProvider;
2572+
}
2573+
25622574
static RetainPtr<NSItemProvider> contactItemForTesting()
25632575
{
25642576
auto contact = adoptNS([allocCNMutableContactInstance() init]);
@@ -2590,6 +2602,22 @@ static void _generateBestRepresentationForRequest(id, SEL)
25902602
EXPECT_WK_STREQ("text/vcard", info.contentType);
25912603
}
25922604

2605+
TEST(WKAttachmentTestsIOS, InsertDroppedCalendarInviteAsAttachment)
2606+
{
2607+
auto itemProvider = calendarInviteForTesting();
2608+
auto webView = webViewForTestingAttachments();
2609+
auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
2610+
[simulator setExternalItemProviders:@[ itemProvider.get() ]];
2611+
[simulator runFrom:CGPointMake(25, 25) to:CGPointMake(100, 100)];
2612+
2613+
[webView expectElementCount:1 querySelector:@"ATTACHMENT"];
2614+
EXPECT_WK_STREQ("text/calendar", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
2615+
EXPECT_EQ(1U, [simulator insertedAttachments].count);
2616+
_WKAttachmentInfo *info = [simulator insertedAttachments].firstObject.info;
2617+
EXPECT_TRUE([info.name containsString:@".ics"]);
2618+
EXPECT_WK_STREQ("text/calendar", info.contentType);
2619+
}
2620+
25932621
TEST(WKAttachmentTestsIOS, InsertDroppedContactAsAttachment)
25942622
{
25952623
auto itemProvider = contactItemForTesting();
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
BEGIN:VCALENDAR
2+
CALSCALE:GREGORIAN
3+
PRODID:-//Apple Inc.//macOS 14.0//EN
4+
VERSION:2.0
5+
BEGIN:VTIMEZONE
6+
TZID:America/Los_Angeles
7+
BEGIN:DAYLIGHT
8+
DTSTART:20070311T020000
9+
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
10+
TZNAME:PDT
11+
TZOFFSETFROM:-0800
12+
TZOFFSETTO:-0700
13+
END:DAYLIGHT
14+
BEGIN:STANDARD
15+
DTSTART:20071104T020000
16+
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
17+
TZNAME:PST
18+
TZOFFSETFROM:-0700
19+
TZOFFSETTO:-0800
20+
END:STANDARD
21+
END:VTIMEZONE
22+
BEGIN:VEVENT
23+
CREATED:20240407T195559Z
24+
DTEND;TZID=America/Los_Angeles:20240407T190000
25+
DTSTAMP:20240407T211845Z
26+
DTSTART;TZID=America/Los_Angeles:20240407T180000
27+
LAST-MODIFIED:20240407T195733Z
28+
SEQUENCE:1
29+
SUMMARY:Test Event
30+
TRANSP:OPAQUE
31+
UID:4750462C-C9FB-4276-ACD9-94481BFF33E2
32+
URL;VALUE=URI:
33+
END:VEVENT
34+
END:VCALENDAR

0 commit comments

Comments
 (0)