1 /*
2 * Copyright (c) 2008, 2009, 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 "Pasteboard.h"
36 #include "PlatformBridge.h"
37
38 namespace WebCore {
39
40 // Per RFC 2483, the line separator for "text/..." MIME types is CR-LF.
41 static char const* const textMIMETypeLineSeparator = "\r\n";
42
clearData(const String & type)43 void ChromiumDataObject::clearData(const String& type)
44 {
45 if (type == mimeTypeTextPlain) {
46 m_plainText = "";
47 return;
48 }
49
50 if (type == mimeTypeURL || type == mimeTypeTextURIList) {
51 m_uriList = "";
52 m_url = KURL();
53 m_urlTitle = "";
54 return;
55 }
56
57 if (type == mimeTypeTextHTML) {
58 m_textHtml = "";
59 m_htmlBaseUrl = KURL();
60 return;
61 }
62
63 if (type == mimeTypeDownloadURL) {
64 m_downloadMetadata = "";
65 return;
66 }
67 }
68
clearAll()69 void ChromiumDataObject::clearAll()
70 {
71 clearAllExceptFiles();
72 m_filenames.clear();
73 }
74
clearAllExceptFiles()75 void ChromiumDataObject::clearAllExceptFiles()
76 {
77 m_urlTitle = "";
78 m_url = KURL();
79 m_uriList = "";
80 m_downloadMetadata = "";
81 m_fileExtension = "";
82 m_plainText = "";
83 m_textHtml = "";
84 m_htmlBaseUrl = KURL();
85 m_fileContentFilename = "";
86 if (m_fileContent)
87 m_fileContent->clear();
88 }
89
hasData() const90 bool ChromiumDataObject::hasData() const
91 {
92 return !m_url.isEmpty()
93 || !m_uriList.isEmpty()
94 || !m_downloadMetadata.isEmpty()
95 || !m_fileExtension.isEmpty()
96 || !m_filenames.isEmpty()
97 || !m_plainText.isEmpty()
98 || !m_textHtml.isEmpty()
99 || m_fileContent;
100 }
101
types() const102 HashSet<String> ChromiumDataObject::types() const
103 {
104 if (m_clipboardType == Clipboard::CopyAndPaste) {
105 bool ignoredContainsFilenames;
106 return PlatformBridge::clipboardReadAvailableTypes(PasteboardPrivate::StandardBuffer,
107 &ignoredContainsFilenames);
108 }
109
110 HashSet<String> results;
111
112 if (!m_plainText.isEmpty()) {
113 results.add(mimeTypeText);
114 results.add(mimeTypeTextPlain);
115 }
116
117 if (m_url.isValid())
118 results.add(mimeTypeURL);
119
120 if (!m_uriList.isEmpty())
121 results.add(mimeTypeTextURIList);
122
123 if (!m_textHtml.isEmpty())
124 results.add(mimeTypeTextHTML);
125
126 return results;
127 }
128
getData(const String & type,bool & success)129 String ChromiumDataObject::getData(const String& type, bool& success)
130 {
131 if (type == mimeTypeTextPlain) {
132 if (m_clipboardType == Clipboard::CopyAndPaste) {
133 PasteboardPrivate::ClipboardBuffer buffer =
134 Pasteboard::generalPasteboard()->isSelectionMode() ?
135 PasteboardPrivate::SelectionBuffer :
136 PasteboardPrivate::StandardBuffer;
137 String text = PlatformBridge::clipboardReadPlainText(buffer);
138 success = !text.isEmpty();
139 return text;
140 }
141 success = !m_plainText.isEmpty();
142 return m_plainText;
143 }
144
145 if (type == mimeTypeURL) {
146 success = !m_url.isEmpty();
147 return m_url.string();
148 }
149
150 if (type == mimeTypeTextURIList) {
151 success = !m_uriList.isEmpty();
152 return m_uriList;
153 }
154
155 if (type == mimeTypeTextHTML) {
156 if (m_clipboardType == Clipboard::CopyAndPaste) {
157 PasteboardPrivate::ClipboardBuffer buffer =
158 Pasteboard::generalPasteboard()->isSelectionMode() ?
159 PasteboardPrivate::SelectionBuffer :
160 PasteboardPrivate::StandardBuffer;
161 String htmlText;
162 KURL sourceURL;
163 PlatformBridge::clipboardReadHTML(buffer, &htmlText, &sourceURL);
164 success = !htmlText.isEmpty();
165 return htmlText;
166 }
167 success = !m_textHtml.isEmpty();
168 return m_textHtml;
169 }
170
171 if (type == mimeTypeDownloadURL) {
172 success = !m_downloadMetadata.isEmpty();
173 return m_downloadMetadata;
174 }
175
176 success = false;
177 return String();
178 }
179
setData(const String & type,const String & data)180 bool ChromiumDataObject::setData(const String& type, const String& data)
181 {
182 if (type == mimeTypeTextPlain) {
183 m_plainText = data;
184 return true;
185 }
186
187 if (type == mimeTypeURL || type == mimeTypeTextURIList) {
188 m_url = KURL();
189 Vector<String> uriList;
190 // Line separator is \r\n per RFC 2483 - however, for compatibility
191 // reasons we also allow just \n here.
192 data.split('\n', uriList);
193 // Process the input and copy the first valid URL into the url member.
194 // In case no URLs can be found, subsequent calls to getData("URL")
195 // will get an empty string. This is in line with the HTML5 spec (see
196 // "The DragEvent and DataTransfer interfaces").
197 for (size_t i = 0; i < uriList.size(); ++i) {
198 String& line = uriList[i];
199 line = line.stripWhiteSpace();
200 if (line.isEmpty()) {
201 continue;
202 }
203 if (line[0] == '#')
204 continue;
205 KURL url = KURL(ParsedURLString, line);
206 if (url.isValid()) {
207 m_url = url;
208 break;
209 }
210 }
211 m_uriList = data;
212 return true;
213 }
214
215 if (type == mimeTypeTextHTML) {
216 m_textHtml = data;
217 m_htmlBaseUrl = KURL();
218 return true;
219 }
220
221 if (type == mimeTypeDownloadURL) {
222 m_downloadMetadata = data;
223 return true;
224 }
225
226 return false;
227 }
228
containsFilenames() const229 bool ChromiumDataObject::containsFilenames() const
230 {
231 bool containsFilenames;
232 if (m_clipboardType == Clipboard::CopyAndPaste) {
233 HashSet<String> ignoredResults =
234 PlatformBridge::clipboardReadAvailableTypes(PasteboardPrivate::StandardBuffer,
235 &containsFilenames);
236 } else
237 containsFilenames = !m_filenames.isEmpty();
238 return containsFilenames;
239 }
240
ChromiumDataObject(Clipboard::ClipboardType clipboardType)241 ChromiumDataObject::ChromiumDataObject(Clipboard::ClipboardType clipboardType)
242 : m_clipboardType(clipboardType)
243 {
244 }
245
ChromiumDataObject(const ChromiumDataObject & other)246 ChromiumDataObject::ChromiumDataObject(const ChromiumDataObject& other)
247 : RefCounted<ChromiumDataObject>()
248 , m_clipboardType(other.m_clipboardType)
249 , m_urlTitle(other.m_urlTitle)
250 , m_downloadMetadata(other.m_downloadMetadata)
251 , m_fileExtension(other.m_fileExtension)
252 , m_filenames(other.m_filenames)
253 , m_plainText(other.m_plainText)
254 , m_textHtml(other.m_textHtml)
255 , m_htmlBaseUrl(other.m_htmlBaseUrl)
256 , m_fileContentFilename(other.m_fileContentFilename)
257 , m_url(other.m_url)
258 , m_uriList(other.m_uriList)
259 {
260 if (other.m_fileContent.get())
261 m_fileContent = other.m_fileContent->copy();
262 }
263
264 } // namespace WebCore
265
266