[Attachment Support] Implement SPI for clients to update a given attachment's data
[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/AttachmentTypes.h>
35 #import <WebCore/SharedBuffer.h>
36 #import <wtf/BlockPtr.h>
37
38 using namespace WebKit;
39
40 @implementation _WKAttachmentDisplayOptions : NSObject
41
42 - (instancetype)init
43 {
44     if (self = [super init])
45         _mode = _WKAttachmentDisplayModeAuto;
46
47     return self;
48 }
49
50 - (WebCore::AttachmentDisplayOptions)coreDisplayOptions
51 {
52     WebCore::AttachmentDisplayMode mode;
53     switch (self.mode) {
54     case _WKAttachmentDisplayModeAuto:
55         mode = WebCore::AttachmentDisplayMode::Auto;
56         break;
57     case _WKAttachmentDisplayModeAsIcon:
58         mode = WebCore::AttachmentDisplayMode::AsIcon;
59         break;
60     case _WKAttachmentDisplayModeInPlace:
61         mode = WebCore::AttachmentDisplayMode::InPlace;
62         break;
63     default:
64         ASSERT_NOT_REACHED();
65         mode = WebCore::AttachmentDisplayMode::Auto;
66     }
67     return { mode };
68 }
69
70 @end
71
72 @implementation _WKAttachment
73
74 - (API::Object&)_apiObject
75 {
76     return *_attachment;
77 }
78
79 - (BOOL)isEqual:(id)object
80 {
81     return [object isKindOfClass:[_WKAttachment class]] && [self.uniqueIdentifier isEqual:[(_WKAttachment *)object uniqueIdentifier]];
82 }
83
84 - (void)requestData:(void(^)(NSData *, NSError *))completionHandler
85 {
86     _attachment->requestData([ capturedBlock = makeBlockPtr(completionHandler) ] (RefPtr<WebCore::SharedBuffer> buffer, CallbackBase::Error error) {
87         if (!capturedBlock)
88             return;
89
90         if (buffer && error == CallbackBase::Error::None)
91             capturedBlock(buffer->createNSData().autorelease(), nil);
92         else
93             capturedBlock(nil, [NSError errorWithDomain:WKErrorDomain code:1 userInfo:nil]);
94     });
95 }
96
97 - (void)setDisplayOptions:(_WKAttachmentDisplayOptions *)options completion:(void(^)(NSError *))completionHandler
98 {
99     auto coreOptions = options ? options.coreDisplayOptions : WebCore::AttachmentDisplayOptions { };
100     _attachment->setDisplayOptions(coreOptions, [capturedBlock = makeBlockPtr(completionHandler)] (CallbackBase::Error error) {
101         if (!capturedBlock)
102             return;
103
104         if (error == CallbackBase::Error::None)
105             capturedBlock(nil);
106         else
107             capturedBlock([NSError errorWithDomain:WKErrorDomain code:1 userInfo:nil]);
108     });
109 }
110
111 - (void)setData:(NSData *)data newContentType:(NSString *)newContentType newFilename:(NSString *)newFilename completion:(void(^)(NSError *))completionHandler
112 {
113     auto buffer = WebCore::SharedBuffer::create(data);
114     _attachment->setDataAndContentType(buffer.get(), newContentType, newFilename, [capturedBlock = makeBlockPtr(completionHandler), capturedBuffer = buffer.copyRef()] (CallbackBase::Error error) {
115         if (!capturedBlock)
116             return;
117
118         if (error == CallbackBase::Error::None)
119             capturedBlock(nil);
120         else
121             capturedBlock([NSError errorWithDomain:WKErrorDomain code:1 userInfo:nil]);
122     });
123 }
124
125 - (NSString *)uniqueIdentifier
126 {
127     return _attachment->identifier();
128 }
129
130 - (NSUInteger)hash
131 {
132     return [self.uniqueIdentifier hash];
133 }
134
135 - (NSString *)description
136 {
137     return [NSString stringWithFormat:@"<%@ id='%@'>", [self class], self.uniqueIdentifier];
138 }
139
140 @end
141
142 #endif // WK_API_ENABLED