Support drag-and-drop for input[type=color]
[WebKit-https.git] / Source / WebKit / UIProcess / Cocoa / WebPasteboardProxyCocoa.mm
1 /*
2  * Copyright (C) 2014 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 "WebPasteboardProxy.h"
28
29 #import "SandboxExtension.h"
30 #import "WebProcessProxy.h"
31 #import <WebCore/Color.h>
32 #import <WebCore/Pasteboard.h>
33 #import <WebCore/PasteboardItemInfo.h>
34 #import <WebCore/PlatformPasteboard.h>
35 #import <WebCore/SharedBuffer.h>
36 #import <WebCore/URL.h>
37
38 using namespace WebCore;
39
40 namespace WebKit {
41
42 void WebPasteboardProxy::getPasteboardTypes(const String& pasteboardName, Vector<String>& pasteboardTypes)
43 {
44     PlatformPasteboard(pasteboardName).getTypes(pasteboardTypes);
45 }
46
47 void WebPasteboardProxy::getPasteboardPathnamesForType(IPC::Connection& connection, const String& pasteboardName, const String& pasteboardType,
48     Vector<String>& pathnames, SandboxExtension::HandleArray& sandboxExtensions)
49 {
50     for (auto* webProcessProxy : m_webProcessProxyList) {
51         if (!webProcessProxy->hasConnection(connection))
52             continue;
53
54         PlatformPasteboard(pasteboardName).getPathnamesForType(pathnames, pasteboardType);
55
56 #if PLATFORM(MAC)
57         // On iOS, files are copied into app's container upon paste.
58         sandboxExtensions.allocate(pathnames.size());
59         for (size_t i = 0; i < pathnames.size(); i++) {
60             auto& filename = pathnames[i];
61             if (![[NSFileManager defaultManager] fileExistsAtPath:filename])
62                 continue;
63             SandboxExtension::createHandle(filename, SandboxExtension::Type::ReadOnly, sandboxExtensions[i]);
64         }
65 #endif
66     }
67 }
68
69 void WebPasteboardProxy::getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, String& string)
70 {
71     string = PlatformPasteboard(pasteboardName).stringForType(pasteboardType);
72 }
73
74 void WebPasteboardProxy::getPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, SharedMemory::Handle& handle, uint64_t& size)
75 {
76     RefPtr<SharedBuffer> buffer = PlatformPasteboard(pasteboardName).bufferForType(pasteboardType);
77     if (!buffer)
78         return;
79     size = buffer->size();
80     if (!size)
81         return;
82     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::allocate(size);
83     if (!sharedMemoryBuffer)
84         return;
85     memcpy(sharedMemoryBuffer->data(), buffer->data(), size);
86     sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
87 }
88
89 void WebPasteboardProxy::pasteboardCopy(const String& fromPasteboard, const String& toPasteboard, uint64_t& newChangeCount)
90 {
91     newChangeCount = PlatformPasteboard(toPasteboard).copy(fromPasteboard);
92 }
93
94 void WebPasteboardProxy::getPasteboardChangeCount(const String& pasteboardName, uint64_t& changeCount)
95 {
96     changeCount = PlatformPasteboard(pasteboardName).changeCount();
97 }
98
99 void WebPasteboardProxy::getPasteboardUniqueName(String& pasteboardName)
100 {
101     pasteboardName = PlatformPasteboard::uniqueName();
102 }
103
104 void WebPasteboardProxy::getPasteboardColor(const String& pasteboardName, WebCore::Color& color)
105 {
106     color = PlatformPasteboard(pasteboardName).color();    
107 }
108
109 void WebPasteboardProxy::getPasteboardURL(const String& pasteboardName, WTF::String& urlString)
110 {
111     urlString = PlatformPasteboard(pasteboardName).url().string();
112 }
113
114 void WebPasteboardProxy::addPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount)
115 {
116     newChangeCount = PlatformPasteboard(pasteboardName).addTypes(pasteboardTypes);
117 }
118
119 void WebPasteboardProxy::setPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount)
120 {
121     newChangeCount = PlatformPasteboard(pasteboardName).setTypes(pasteboardTypes);
122 }
123
124 void WebPasteboardProxy::setPasteboardURL(IPC::Connection& connection, const PasteboardURL& pasteboardURL, const String& pasteboardName, uint64_t& newChangeCount)
125 {
126     for (auto* webProcessProxy : m_webProcessProxyList) {
127         if (!webProcessProxy->hasConnection(connection))
128             continue;
129
130         if (!webProcessProxy->checkURLReceivedFromWebProcess(pasteboardURL.url.string())) {
131             newChangeCount = 0;
132             return;
133         }
134
135         newChangeCount = PlatformPasteboard(pasteboardName).setURL(pasteboardURL);
136         return;
137     }
138     newChangeCount = 0;
139 }
140
141 void WebPasteboardProxy::setPasteboardColor(const String& pasteboardName, const WebCore::Color& color, uint64_t& newChangeCount)
142 {
143     newChangeCount = PlatformPasteboard(pasteboardName).setColor(color);
144 }
145
146 void WebPasteboardProxy::setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String& string, uint64_t& newChangeCount)
147 {
148     newChangeCount = PlatformPasteboard(pasteboardName).setStringForType(string, pasteboardType);
149 }
150
151 void WebPasteboardProxy::setPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, const SharedMemory::Handle& handle, uint64_t size, uint64_t& newChangeCount)
152 {
153     if (handle.isNull()) {
154         newChangeCount = PlatformPasteboard(pasteboardName).setBufferForType(0, pasteboardType);
155         return;
156     }
157     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly);
158     RefPtr<SharedBuffer> buffer = SharedBuffer::create(static_cast<unsigned char *>(sharedMemoryBuffer->data()), size);
159     newChangeCount = PlatformPasteboard(pasteboardName).setBufferForType(buffer.get(), pasteboardType);
160 }
161
162 void WebPasteboardProxy::getNumberOfFiles(const String& pasteboardName, uint64_t& numberOfFiles)
163 {
164     numberOfFiles = PlatformPasteboard(pasteboardName).numberOfFiles();
165 }
166
167 void WebPasteboardProxy::typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin, Vector<String>& types)
168 {
169     types = PlatformPasteboard(pasteboardName).typesSafeForDOMToReadAndWrite(origin);
170 }
171
172 void WebPasteboardProxy::writeCustomData(const WebCore::PasteboardCustomData& data, const String& pasteboardName, uint64_t& newChangeCount)
173 {
174     newChangeCount = PlatformPasteboard(pasteboardName).write(data);
175 }
176
177 #if PLATFORM(IOS)
178 void WebPasteboardProxy::getPasteboardTypesByFidelityForItemAtIndex(uint64_t index, const String& pasteboardName, Vector<String>& types)
179 {
180     PlatformPasteboard(pasteboardName).getTypesByFidelityForItemAtIndex(types, index);
181 }
182
183 void WebPasteboardProxy::writeURLToPasteboard(const PasteboardURL& url, const String& pasteboardName)
184 {
185     PlatformPasteboard(pasteboardName).write(url);
186 }
187
188 void WebPasteboardProxy::writeWebContentToPasteboard(const WebCore::PasteboardWebContent& content, const String& pasteboardName)
189 {
190     PlatformPasteboard(pasteboardName).write(content);
191 }
192
193 void WebPasteboardProxy::writeImageToPasteboard(const WebCore::PasteboardImage& pasteboardImage, const String& pasteboardName)
194 {
195     PlatformPasteboard(pasteboardName).write(pasteboardImage);
196 }
197
198 void WebPasteboardProxy::writeStringToPasteboard(const String& pasteboardType, const String& text, const String& pasteboardName)
199 {
200     PlatformPasteboard(pasteboardName).write(pasteboardType, text);
201 }
202
203 void WebPasteboardProxy::readStringFromPasteboard(uint64_t index, const String& pasteboardType, const String& pasteboardName, WTF::String& value)
204 {
205     value = PlatformPasteboard(pasteboardName).readString(index, pasteboardType);
206 }
207
208 void WebPasteboardProxy::readURLFromPasteboard(uint64_t index, const String& pasteboardType, const String& pasteboardName, String& url, String& title)
209 {
210     url = PlatformPasteboard(pasteboardName).readURL(index, pasteboardType, title);
211 }
212
213 void WebPasteboardProxy::readBufferFromPasteboard(uint64_t index, const String& pasteboardType, const String& pasteboardName, SharedMemory::Handle& handle, uint64_t& size)
214 {
215     RefPtr<SharedBuffer> buffer = PlatformPasteboard(pasteboardName).readBuffer(index, pasteboardType);
216     if (!buffer)
217         return;
218     size = buffer->size();
219     if (!size)
220         return;
221     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::allocate(size);
222     if (!sharedMemoryBuffer)
223         return;
224     memcpy(sharedMemoryBuffer->data(), buffer->data(), size);
225     sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
226 }
227
228 void WebPasteboardProxy::getPasteboardItemsCount(const String& pasteboardName, uint64_t& itemsCount)
229 {
230     itemsCount = PlatformPasteboard(pasteboardName).count();
231 }
232
233 void WebPasteboardProxy::allPasteboardItemInfo(const String& pasteboardName, Vector<PasteboardItemInfo>& allInfo)
234 {
235     allInfo = PlatformPasteboard(pasteboardName).allPasteboardItemInfo();
236 }
237
238 void WebPasteboardProxy::informationForItemAtIndex(int index, const String& pasteboardName, PasteboardItemInfo& info)
239 {
240     info = PlatformPasteboard(pasteboardName).informationForItemAtIndex(index);
241 }
242
243 void WebPasteboardProxy::updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName)
244 {
245     PlatformPasteboard(pasteboardName).updateSupportedTypeIdentifiers(identifiers);
246 }
247
248 #endif
249
250 } // namespace WebKit