Move URL from WebCore to WTF
[WebKit-https.git] / Source / WebCore / platform / gtk / PasteboardGtk.cpp
1 /*
2  *  Copyright (C) 2007 Holger Hans Peter Freyther
3  *  Copyright (C) 2007 Alp Toker <alp@atoker.com>
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19
20 #include "config.h"
21 #include "Pasteboard.h"
22
23 #include "Color.h"
24 #include "DragData.h"
25 #include "Image.h"
26 #include "NotImplemented.h"
27 #include "PasteboardStrategy.h"
28 #include "PlatformStrategies.h"
29 #include "SelectionData.h"
30 #include <wtf/NeverDestroyed.h>
31 #include <wtf/URL.h>
32
33 namespace WebCore {
34
35 enum ClipboardDataType {
36     ClipboardDataTypeText,
37     ClipboardDataTypeMarkup,
38     ClipboardDataTypeURIList,
39     ClipboardDataTypeURL,
40     ClipboardDataTypeImage,
41     ClipboardDataTypeUnknown
42 };
43
44 std::unique_ptr<Pasteboard> Pasteboard::createForCopyAndPaste()
45 {
46     return std::make_unique<Pasteboard>("CLIPBOARD");
47 }
48
49 std::unique_ptr<Pasteboard> Pasteboard::createForGlobalSelection()
50 {
51     return std::make_unique<Pasteboard>("PRIMARY");
52 }
53
54 #if ENABLE(DRAG_SUPPORT)
55 std::unique_ptr<Pasteboard> Pasteboard::createForDragAndDrop()
56 {
57     return std::make_unique<Pasteboard>(SelectionData::create());
58 }
59
60 std::unique_ptr<Pasteboard> Pasteboard::createForDragAndDrop(const DragData& dragData)
61 {
62     ASSERT(dragData.platformData());
63     return std::make_unique<Pasteboard>(*dragData.platformData());
64 }
65 #endif
66
67 Pasteboard::Pasteboard(SelectionData& selectionData)
68     : m_selectionData(selectionData)
69 {
70 }
71
72 Pasteboard::Pasteboard(const String& name)
73     : m_selectionData(SelectionData::create())
74     , m_name(name)
75 {
76 }
77
78 Pasteboard::Pasteboard()
79     : m_selectionData(SelectionData::create())
80 {
81 }
82
83 Pasteboard::~Pasteboard() = default;
84
85 const SelectionData& Pasteboard::selectionData() const
86 {
87     return m_selectionData.get();
88 }
89
90 static ClipboardDataType selectionDataTypeFromHTMLClipboardType(const String& type)
91 {
92     // From the Mac port: Ignore any trailing charset - JS strings are
93     // Unicode, which encapsulates the charset issue.
94     if (type == "text/plain")
95         return ClipboardDataTypeText;
96     if (type == "text/html")
97         return ClipboardDataTypeMarkup;
98     if (type == "Files" || type == "text/uri-list")
99         return ClipboardDataTypeURIList;
100
101     // Not a known type, so just default to using the text portion.
102     return ClipboardDataTypeUnknown;
103 }
104
105 void Pasteboard::writeToClipboard()
106 {
107     if (m_name.isNull())
108         return;
109
110     platformStrategies()->pasteboardStrategy()->writeToClipboard(m_name, m_selectionData);
111 }
112
113 void Pasteboard::readFromClipboard()
114 {
115     if (m_name.isNull())
116         return;
117     m_selectionData = platformStrategies()->pasteboardStrategy()->readFromClipboard(m_name);
118 }
119
120 void Pasteboard::writeString(const String& type, const String& data)
121 {
122     switch (selectionDataTypeFromHTMLClipboardType(type)) {
123     case ClipboardDataTypeURIList:
124     case ClipboardDataTypeURL:
125         m_selectionData->setURIList(data);
126         break;
127     case ClipboardDataTypeMarkup:
128         m_selectionData->setMarkup(data);
129         break;
130     case ClipboardDataTypeText:
131         m_selectionData->setText(data);
132         break;
133     case ClipboardDataTypeUnknown:
134         m_selectionData->setUnknownTypeData(type, data);
135         break;
136     case ClipboardDataTypeImage:
137         break;
138     }
139     writeToClipboard();
140 }
141
142 void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
143 {
144     m_selectionData->clearAll();
145     m_selectionData->setText(text);
146     m_selectionData->setCanSmartReplace(smartReplaceOption == CanSmartReplace);
147
148     writeToClipboard();
149 }
150
151 void Pasteboard::write(const PasteboardURL& pasteboardURL)
152 {
153     ASSERT(!pasteboardURL.url.isEmpty());
154
155     m_selectionData->clearAll();
156     m_selectionData->setURL(pasteboardURL.url, pasteboardURL.title);
157
158     writeToClipboard();
159 }
160
161 void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL&)
162 {
163     notImplemented();
164 }
165
166 void Pasteboard::write(const PasteboardImage& pasteboardImage)
167 {
168     m_selectionData->clearAll();
169     if (!pasteboardImage.url.url.isEmpty()) {
170         m_selectionData->setURL(pasteboardImage.url.url, pasteboardImage.url.title);
171         m_selectionData->setMarkup(pasteboardImage.url.markup);
172     }
173     m_selectionData->setImage(pasteboardImage.image.get());
174
175     writeToClipboard();
176 }
177
178 void Pasteboard::write(const PasteboardWebContent& pasteboardContent)
179 {
180     m_selectionData->clearAll();
181     m_selectionData->setText(pasteboardContent.text);
182     m_selectionData->setMarkup(pasteboardContent.markup);
183     m_selectionData->setCanSmartReplace(pasteboardContent.canSmartCopyOrDelete);
184
185     writeToClipboard();
186 }
187
188 void Pasteboard::clear()
189 {
190     // We do not clear filenames. According to the spec: "The clearData() method
191     // does not affect whether any files were included in the drag, so the types
192     // attribute's list might still not be empty after calling clearData() (it would
193     // still contain the "Files" string if any files were included in the drag)."
194     m_selectionData->clearAllExceptFilenames();
195     writeToClipboard();
196 }
197
198 void Pasteboard::clear(const String& type)
199 {
200     switch (selectionDataTypeFromHTMLClipboardType(type)) {
201     case ClipboardDataTypeURIList:
202     case ClipboardDataTypeURL:
203         m_selectionData->clearURIList();
204         break;
205     case ClipboardDataTypeMarkup:
206         m_selectionData->clearMarkup();
207         break;
208     case ClipboardDataTypeText:
209         m_selectionData->clearText();
210         break;
211     case ClipboardDataTypeImage:
212         m_selectionData->clearImage();
213         break;
214     case ClipboardDataTypeUnknown:
215         m_selectionData->clearAll();
216         break;
217     }
218
219     writeToClipboard();
220 }
221
222 bool Pasteboard::canSmartReplace()
223 {
224     readFromClipboard();
225     return m_selectionData->canSmartReplace();
226 }
227
228 #if ENABLE(DRAG_SUPPORT)
229 void Pasteboard::setDragImage(DragImage, const IntPoint&)
230 {
231 }
232 #endif
233
234 void Pasteboard::read(PasteboardPlainText& text)
235 {
236     readFromClipboard();
237     text.text = m_selectionData->text();
238 }
239
240 void Pasteboard::read(PasteboardWebContentReader&, WebContentReadingPolicy)
241 {
242 }
243
244 void Pasteboard::read(PasteboardFileReader& reader)
245 {
246     readFromClipboard();
247     for (auto& filename : m_selectionData->filenames())
248         reader.readFilename(filename);
249 }
250
251 bool Pasteboard::hasData()
252 {
253     readFromClipboard();
254     return m_selectionData->hasText() || m_selectionData->hasMarkup() || m_selectionData->hasURIList() || m_selectionData->hasImage() || m_selectionData->hasUnknownTypeData();
255 }
256
257 Vector<String> Pasteboard::typesSafeForBindings(const String&)
258 {
259     notImplemented(); // webkit.org/b/177633: [GTK] Move to new Pasteboard API
260     return { };
261 }
262
263 Vector<String> Pasteboard::typesForLegacyUnsafeBindings()
264 {
265     readFromClipboard();
266
267     Vector<String> types;
268     if (m_selectionData->hasText()) {
269         types.append("text/plain"_s);
270         types.append("Text"_s);
271         types.append("text"_s);
272     }
273
274     if (m_selectionData->hasMarkup())
275         types.append("text/html"_s);
276
277     if (m_selectionData->hasURIList()) {
278         types.append("text/uri-list"_s);
279         types.append("URL"_s);
280     }
281
282     for (auto& key : m_selectionData->unknownTypes().keys())
283         types.append(key);
284
285     return types;
286 }
287
288 String Pasteboard::readOrigin()
289 {
290     notImplemented(); // webkit.org/b/177633: [GTK] Move to new Pasteboard API
291     return { };
292 }
293
294 String Pasteboard::readString(const String& type)
295 {
296     readFromClipboard();
297
298     switch (selectionDataTypeFromHTMLClipboardType(type)) {
299     case ClipboardDataTypeURIList:
300         return m_selectionData->uriList();
301     case ClipboardDataTypeURL:
302         return m_selectionData->url();
303     case ClipboardDataTypeMarkup:
304         return m_selectionData->markup();
305     case ClipboardDataTypeText:
306         return m_selectionData->text();
307     case ClipboardDataTypeUnknown:
308         return m_selectionData->unknownTypeData(type);
309     case ClipboardDataTypeImage:
310         break;
311     }
312
313     return String();
314 }
315
316 String Pasteboard::readStringInCustomData(const String&)
317 {
318     notImplemented(); // webkit.org/b/177633: [GTK] Move to new Pasteboard API
319     return { };
320 }
321
322 Pasteboard::FileContentState Pasteboard::fileContentState()
323 {
324     readFromClipboard();
325     return m_selectionData->filenames().isEmpty() ? FileContentState::NoFileOrImageData : FileContentState::MayContainFilePaths;
326 }
327
328 void Pasteboard::writeMarkup(const String&)
329 {
330 }
331
332 void Pasteboard::writeCustomData(const PasteboardCustomData&)
333 {
334 }
335
336 void Pasteboard::write(const Color&)
337 {
338 }
339
340 }