[Attachment Support] Remove WebCore::AttachmentDisplayOptions and friends
[WebKit-https.git] / Source / WebKit / UIProcess / API / Cocoa / _WKAttachment.mm
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "_WKAttachment.h"
28
29 #if WK_API_ENABLED
30
31 #import "APIAttachment.h"
32 #import "WKErrorPrivate.h"
33 #import "_WKAttachmentInternal.h"
34 #import <WebCore/MIMETypeRegistry.h>
35 #import <WebCore/SharedBuffer.h>
36 #import <wtf/BlockPtr.h>
37
38 #if PLATFORM(IOS)
39 #import <MobileCoreServices/MobileCoreServices.h>
40 #endif
41
42 using namespace WebKit;
43
44 static const NSInteger UnspecifiedAttachmentErrorCode = 1;
45 static const NSInteger InvalidAttachmentErrorCode = 2;
46
47 @implementation _WKAttachmentDisplayOptions : NSObject
48 @end
49
50 @implementation _WKAttachmentInfo {
51     RetainPtr<NSFileWrapper> _fileWrapper;
52     RetainPtr<NSString> _mimeType;
53     RetainPtr<NSString> _utiType;
54     RetainPtr<NSString> _filePath;
55 }
56
57 - (instancetype)initWithFileWrapper:(NSFileWrapper *)fileWrapper filePath:(NSString *)filePath mimeType:(NSString *)mimeType utiType:(NSString *)utiType
58 {
59     if (!(self = [super init]))
60         return nil;
61
62     _fileWrapper = fileWrapper;
63     _filePath = filePath;
64     _mimeType = mimeType;
65     _utiType = utiType;
66     return self;
67 }
68
69 - (NSData *)data
70 {
71     if (![_fileWrapper isRegularFile]) {
72         // FIXME: Handle attachments backed by NSFileWrappers that represent directories.
73         return nil;
74     }
75
76     return [_fileWrapper regularFileContents];
77 }
78
79 - (NSString *)name
80 {
81     if ([_fileWrapper filename].length)
82         return [_fileWrapper filename];
83
84     return [_fileWrapper preferredFilename];
85 }
86
87 - (NSString *)filePath
88 {
89     return _filePath.get();
90 }
91
92 - (NSFileWrapper *)fileWrapper
93 {
94     return _fileWrapper.get();
95 }
96
97 - (NSString *)contentType
98 {
99     if ([_mimeType length])
100         return _mimeType.get();
101
102     return _utiType.get();
103 }
104
105 @end
106
107 @implementation _WKAttachment
108
109 - (API::Object&)_apiObject
110 {
111     return *_attachment;
112 }
113
114 - (_WKAttachmentInfo *)info
115 {
116     if (!_attachment->isValid())
117         return nil;
118
119     return [[[_WKAttachmentInfo alloc] initWithFileWrapper:_attachment->fileWrapper() filePath:_attachment->filePath() mimeType:_attachment->mimeType() utiType:_attachment->utiType()] autorelease];
120 }
121
122 - (void)requestInfo:(void(^)(_WKAttachmentInfo *, NSError *))completionHandler
123 {
124     completionHandler(self.info, nil);
125 }
126
127 - (void)setFileWrapper:(NSFileWrapper *)fileWrapper contentType:(NSString *)contentType completion:(void (^)(NSError *))completionHandler
128 {
129     if (!_attachment->isValid()) {
130         completionHandler([NSError errorWithDomain:WKErrorDomain code:InvalidAttachmentErrorCode userInfo:nil]);
131         return;
132     }
133
134     // This file path member is only populated when the attachment is generated upon dropping files. When data is specified via NSFileWrapper
135     // from the SPI client, the corresponding file path of the data is unknown, if it even exists at all.
136     _attachment->setFilePath({ });
137     _attachment->setFileWrapperAndUpdateContentType(fileWrapper, contentType);
138     _attachment->updateAttributes([capturedBlock = makeBlockPtr(completionHandler)] (auto error) {
139         if (!capturedBlock)
140             return;
141
142         if (error == CallbackBase::Error::None)
143             capturedBlock(nil);
144         else
145             capturedBlock([NSError errorWithDomain:WKErrorDomain code:UnspecifiedAttachmentErrorCode userInfo:nil]);
146     });
147 }
148
149 - (void)setData:(NSData *)data newContentType:(NSString *)newContentType newFilename:(NSString *)newFilename completion:(void(^)(NSError *))completionHandler
150 {
151     auto fileWrapper = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:data]);
152     if (newFilename)
153         [fileWrapper setPreferredFilename:newFilename];
154     [self setFileWrapper:fileWrapper.get() contentType:newContentType completion:completionHandler];
155 }
156
157 - (NSString *)uniqueIdentifier
158 {
159     return _attachment->identifier();
160 }
161
162 - (NSString *)description
163 {
164     return [NSString stringWithFormat:@"<%@ %p id='%@'>", [self class], self, self.uniqueIdentifier];
165 }
166
167 - (BOOL)isConnected
168 {
169     return _attachment->insertionState() == API::Attachment::InsertionState::Inserted;
170 }
171
172 @end
173
174 #endif // WK_API_ENABLED