9b11f23fe3cb035895bbe7afe2d12efd8ce44622
[WebKit-https.git] / Source / WebCore / platform / chromium / ChromiumDataObject.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2012 Google 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 are
6  * met:
7  * 
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  * 
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "ChromiumDataObject.h"
33
34 #include "ClipboardMimeTypes.h"
35 #include "ClipboardUtilitiesChromium.h"
36 #include "DataTransferItem.h"
37 #include "ExceptionCode.h"
38 #include "ExceptionCodePlaceholder.h"
39
40 #include <public/Platform.h>
41 #include <public/WebClipboard.h>
42
43 namespace WebCore {
44
45 PassRefPtr<ChromiumDataObject> ChromiumDataObject::createFromPasteboard()
46 {
47     RefPtr<ChromiumDataObject> dataObject = create();
48     uint64_t sequenceNumber = WebKit::Platform::current()->clipboard()->sequenceNumber(currentPasteboardBuffer());
49     bool ignored;
50     WebKit::WebVector<WebKit::WebString> webTypes = WebKit::Platform::current()->clipboard()->readAvailableTypes(currentPasteboardBuffer(), &ignored);
51     ListHashSet<String> types;
52     for (size_t i = 0; i < webTypes.size(); ++i)
53         types.add(webTypes[i]);
54     for (ListHashSet<String>::const_iterator it = types.begin(); it != types.end(); ++it)
55         dataObject->m_itemList.append(ChromiumDataObjectItem::createFromPasteboard(*it, sequenceNumber));
56     return dataObject.release();
57 }
58
59 PassRefPtr<ChromiumDataObject> ChromiumDataObject::create()
60 {
61     return adoptRef(new ChromiumDataObject());
62 }
63
64 PassRefPtr<ChromiumDataObject> ChromiumDataObject::copy() const
65 {
66     return adoptRef(new ChromiumDataObject(*this));
67 }
68
69 size_t ChromiumDataObject::length() const
70 {
71     return m_itemList.size();
72 }
73
74 PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::item(unsigned long index)
75 {
76     if (index >= length())
77         return 0;
78     return m_itemList[index];
79 }
80
81 void ChromiumDataObject::deleteItem(unsigned long index)
82 {
83     if (index >= length())
84         return;
85     m_itemList.remove(index);
86 }
87
88 void ChromiumDataObject::clearAll()
89 {
90     m_itemList.clear();
91 }
92
93 void ChromiumDataObject::add(const String& data, const String& type, ExceptionCode& ec)
94 {
95     if (!internalAddStringItem(ChromiumDataObjectItem::createFromString(type, data)))
96         ec = NOT_SUPPORTED_ERR;
97 }
98
99 void ChromiumDataObject::add(PassRefPtr<File> file, ScriptExecutionContext* context)
100 {
101     if (!file)
102         return;
103
104     m_itemList.append(ChromiumDataObjectItem::createFromFile(file));
105 }
106
107 void ChromiumDataObject::clearData(const String& type)
108 {
109     for (size_t i = 0; i < m_itemList.size(); ++i) {
110         if (m_itemList[i]->kind() == DataTransferItem::kindString && m_itemList[i]->type() == type) {
111             // Per the spec, type must be unique among all items of kind 'string'.
112             m_itemList.remove(i);
113             return;
114         }
115     }
116 }
117
118 void ChromiumDataObject::clearAllExceptFiles()
119 {
120     for (size_t i = 0; i < m_itemList.size(); ) {
121         if (m_itemList[i]->kind() != DataTransferItem::kindFile) {
122             m_itemList.remove(i);
123             continue;
124         }
125         ++i;
126     }
127 }
128
129 ListHashSet<String> ChromiumDataObject::types() const
130 {
131     ListHashSet<String> results;
132     bool containsFiles = false;
133     for (size_t i = 0; i < m_itemList.size(); ++i) {
134         if (m_itemList[i]->kind() == DataTransferItem::kindString)
135             results.add(m_itemList[i]->type());
136         else if (m_itemList[i]->kind() == DataTransferItem::kindFile)
137             containsFiles = true;
138         else
139             ASSERT_NOT_REACHED();
140     }
141     if (containsFiles)
142         results.add(mimeTypeFiles);
143     return results;
144 }
145
146 String ChromiumDataObject::getData(const String& type) const
147 {
148     for (size_t i = 0; i < m_itemList.size(); ++i)  {
149         if (m_itemList[i]->kind() == DataTransferItem::kindString && m_itemList[i]->type() == type)
150             return m_itemList[i]->internalGetAsString();
151     }
152     return String();
153 }
154
155 bool ChromiumDataObject::setData(const String& type, const String& data)
156 {
157     clearData(type);
158     add(data, type, ASSERT_NO_EXCEPTION);
159     return true;
160 }
161
162 void ChromiumDataObject::urlAndTitle(String& url, String* title) const
163 {
164     RefPtr<ChromiumDataObjectItem> item = findStringItem(mimeTypeTextURIList);
165     if (!item)
166         return;
167     url = convertURIListToURL(item->internalGetAsString());
168     if (title)
169         *title = item->title();
170 }
171
172 void ChromiumDataObject::setURLAndTitle(const String& url, const String& title)
173 {
174     clearData(mimeTypeTextURIList);
175     internalAddStringItem(ChromiumDataObjectItem::createFromURL(url, title));
176 }
177
178 void ChromiumDataObject::htmlAndBaseURL(String& html, KURL& baseURL) const
179 {
180     RefPtr<ChromiumDataObjectItem> item = findStringItem(mimeTypeTextHTML);
181     if (!item)
182         return;
183     html = item->internalGetAsString();
184     baseURL = item->baseURL();
185 }
186
187 void ChromiumDataObject::setHTMLAndBaseURL(const String& html, const KURL& baseURL)
188 {
189     clearData(mimeTypeTextHTML);
190     internalAddStringItem(ChromiumDataObjectItem::createFromHTML(html, baseURL));
191 }
192
193 bool ChromiumDataObject::containsFilenames() const
194 {
195     for (size_t i = 0; i < m_itemList.size(); ++i)
196         if (m_itemList[i]->isFilename())
197             return true;
198     return false;
199 }
200
201 Vector<String> ChromiumDataObject::filenames() const
202 {
203     Vector<String> results;
204     for (size_t i = 0; i < m_itemList.size(); ++i)
205         if (m_itemList[i]->isFilename())
206             results.append(static_cast<File*>(m_itemList[i]->getAsFile().get())->path());
207     return results;
208 }
209
210 void ChromiumDataObject::addFilename(const String& filename, const String& displayName)
211 {
212     internalAddFileItem(ChromiumDataObjectItem::createFromFile(File::createWithName(filename, displayName, File::AllContentTypes)));
213 }
214
215 void ChromiumDataObject::addSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
216 {
217     internalAddFileItem(ChromiumDataObjectItem::createFromSharedBuffer(name, buffer));
218 }
219
220 ChromiumDataObject::ChromiumDataObject()
221     : m_modifierKeyState(0)
222 {
223 }
224
225 ChromiumDataObject::ChromiumDataObject(const ChromiumDataObject& other)
226     : RefCounted<ChromiumDataObject>()
227     , m_itemList(other.m_itemList)
228     , m_modifierKeyState(0)
229 {
230 }
231
232 PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::findStringItem(const String& type) const
233 {
234     for (size_t i = 0; i < m_itemList.size(); ++i) {
235         if (m_itemList[i]->kind() == DataTransferItem::kindString && m_itemList[i]->type() == type)
236             return m_itemList[i];
237     }
238     return 0;
239 }
240
241 bool ChromiumDataObject::internalAddStringItem(PassRefPtr<ChromiumDataObjectItem> item)
242 {
243     ASSERT(item->kind() == DataTransferItem::kindString);
244     for (size_t i = 0; i < m_itemList.size(); ++i)
245         if (m_itemList[i]->kind() == DataTransferItem::kindString && m_itemList[i]->type() == item->type())
246             return false;
247
248     m_itemList.append(item);
249     return true;
250 }
251
252 void ChromiumDataObject::internalAddFileItem(PassRefPtr<ChromiumDataObjectItem> item)
253 {
254     ASSERT(item->kind() == DataTransferItem::kindFile);
255     m_itemList.append(item);
256 }
257
258 } // namespace WebCore