blob: 3cbe45c7c14d492591c384dce565e5580fc1d9e4 [file] [log] [blame]
[email protected]fbf75412012-01-07 01:26:521// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]2dfeaf92011-01-10 21:08:212// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]c62ce3e2009-02-26 00:15:204
[email protected]c62ce3e2009-02-26 00:15:205#include "webkit/glue/webclipboard_impl.h"
6
[email protected]c62ce3e2009-02-26 00:15:207#include "base/logging.h"
[email protected]2ffbb482011-12-05 23:41:178#include "base/pickle.h"
[email protected]c62ce3e2009-02-26 00:15:209#include "base/string_util.h"
[email protected]b1e4eb502010-03-07 20:53:3310#include "base/utf_string_conversions.h"
[email protected]c62ce3e2009-02-26 00:15:2011#include "googleurl/src/gurl.h"
12#include "net/base/escape.h"
[email protected]445852d2013-01-15 16:55:3913#include "third_party/WebKit/Source/Platform/chromium/public/WebData.h"
14#include "third_party/WebKit/Source/Platform/chromium/public/WebDragData.h"
15#include "third_party/WebKit/Source/Platform/chromium/public/WebImage.h"
16#include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
17#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
18#include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
19#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
[email protected]8973f522009-07-03 05:58:4520#include "third_party/skia/include/core/SkBitmap.h"
[email protected]2dfeaf92011-01-10 21:08:2121#include "ui/base/clipboard/clipboard.h"
[email protected]2ffbb482011-12-05 23:41:1722#include "ui/base/clipboard/custom_data_helper.h"
[email protected]c62ce3e2009-02-26 00:15:2023#include "webkit/glue/scoped_clipboard_writer_glue.h"
[email protected]2ffbb482011-12-05 23:41:1724#include "webkit/glue/webdropdata.h"
[email protected]c62ce3e2009-02-26 00:15:2025#include "webkit/glue/webkit_glue.h"
26
27using WebKit::WebClipboard;
[email protected]3d4a6912011-03-15 20:56:1928using WebKit::WebData;
[email protected]3f0318292011-11-18 21:49:0029using WebKit::WebDragData;
[email protected]c62ce3e2009-02-26 00:15:2030using WebKit::WebImage;
31using WebKit::WebString;
32using WebKit::WebURL;
[email protected]97c2c032010-07-07 22:43:4133using WebKit::WebVector;
[email protected]c62ce3e2009-02-26 00:15:2034
35namespace webkit_glue {
36
[email protected]b9a0b1b32009-03-30 23:09:3737// Static
38std::string WebClipboardImpl::URLToMarkup(const WebURL& url,
39 const WebString& title) {
[email protected]c62ce3e2009-02-26 00:15:2040 std::string markup("<a href=\"");
41 markup.append(url.spec());
42 markup.append("\">");
43 // TODO(darin): HTML escape this
[email protected]a0200c52011-10-13 14:19:2744 markup.append(net::EscapeForHTML(UTF16ToUTF8(title)));
[email protected]c62ce3e2009-02-26 00:15:2045 markup.append("</a>");
46 return markup;
47}
48
[email protected]b9a0b1b32009-03-30 23:09:3749// Static
50std::string WebClipboardImpl::URLToImageMarkup(const WebURL& url,
51 const WebString& title) {
[email protected]c62ce3e2009-02-26 00:15:2052 std::string markup("<img src=\"");
53 markup.append(url.spec());
54 markup.append("\"");
55 if (!title.isEmpty()) {
56 markup.append(" alt=\"");
[email protected]a0200c52011-10-13 14:19:2757 markup.append(net::EscapeForHTML(UTF16ToUTF8(title)));
[email protected]c62ce3e2009-02-26 00:15:2058 markup.append("\"");
59 }
60 markup.append("/>");
61 return markup;
62}
63
[email protected]0de5d8602011-11-22 03:48:5264WebClipboardImpl::WebClipboardImpl(ClipboardClient* client)
65 : client_(client) {
66}
67
[email protected]04bf3ad2010-08-27 21:23:4868WebClipboardImpl::~WebClipboardImpl() {
69}
70
[email protected]36780a12011-11-04 18:16:4471uint64 WebClipboardImpl::getSequenceNumber() {
[email protected]9cf12c32011-11-10 19:28:0772 return sequenceNumber(BufferStandard);
73}
74
75uint64 WebClipboardImpl::sequenceNumber(Buffer buffer) {
76 ui::Clipboard::Buffer buffer_type;
77 if (!ConvertBufferType(buffer, &buffer_type))
78 return 0;
79
[email protected]0de5d8602011-11-22 03:48:5280 return client_->GetSequenceNumber(buffer_type);
[email protected]36780a12011-11-04 18:16:4481}
82
[email protected]65a6150d2009-09-08 22:16:0583bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
[email protected]757d4e542012-01-20 22:23:4284 ui::Clipboard::Buffer buffer_type = ui::Clipboard::BUFFER_STANDARD;
[email protected]c62ce3e2009-02-26 00:15:2085
[email protected]606876c2011-03-24 17:13:3886 if (!ConvertBufferType(buffer, &buffer_type))
87 return false;
88
[email protected]c62ce3e2009-02-26 00:15:2089 switch (format) {
[email protected]606876c2011-03-24 17:13:3890 case FormatPlainText:
[email protected]0de5d8602011-11-22 03:48:5291 return client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]606876c2011-03-24 17:13:3892 buffer_type) ||
[email protected]0de5d8602011-11-22 03:48:5293 client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]606876c2011-03-24 17:13:3894 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2095 case FormatHTML:
[email protected]ff53be62011-12-07 23:28:2996 return client_->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(),
97 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2098 case FormatSmartPaste:
[email protected]ff53be62011-12-07 23:28:2999 return client_->IsFormatAvailable(
100 ui::Clipboard::GetWebKitSmartPasteFormatType(), buffer_type);
[email protected]c62ce3e2009-02-26 00:15:20101 case FormatBookmark:
102#if defined(OS_WIN) || defined(OS_MACOSX)
[email protected]ff53be62011-12-07 23:28:29103 return client_->IsFormatAvailable(ui::Clipboard::GetUrlWFormatType(),
104 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:20105#endif
106 default:
107 NOTREACHED();
[email protected]c62ce3e2009-02-26 00:15:20108 }
109
[email protected]ff53be62011-12-07 23:28:29110 return false;
[email protected]c62ce3e2009-02-26 00:15:20111}
112
[email protected]36780a12011-11-04 18:16:44113WebVector<WebString> WebClipboardImpl::readAvailableTypes(
114 Buffer buffer, bool* contains_filenames) {
115 ui::Clipboard::Buffer buffer_type;
[email protected]82758352013-03-29 19:21:31116 std::vector<base::string16> types;
[email protected]36780a12011-11-04 18:16:44117 if (ConvertBufferType(buffer, &buffer_type)) {
[email protected]0de5d8602011-11-22 03:48:52118 client_->ReadAvailableTypes(buffer_type, &types, contains_filenames);
[email protected]36780a12011-11-04 18:16:44119 }
120 return types;
121}
122
[email protected]65a6150d2009-09-08 22:16:05123WebString WebClipboardImpl::readPlainText(Buffer buffer) {
[email protected]2dfeaf92011-01-10 21:08:21124 ui::Clipboard::Buffer buffer_type;
[email protected]65a6150d2009-09-08 22:16:05125 if (!ConvertBufferType(buffer, &buffer_type))
126 return WebString();
127
[email protected]0de5d8602011-11-22 03:48:52128 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]65a6150d2009-09-08 22:16:05129 buffer_type)) {
[email protected]82758352013-03-29 19:21:31130 base::string16 text;
[email protected]0de5d8602011-11-22 03:48:52131 client_->ReadText(buffer_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20132 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36133 return text;
[email protected]c62ce3e2009-02-26 00:15:20134 }
135
[email protected]0de5d8602011-11-22 03:48:52136 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]65a6150d2009-09-08 22:16:05137 buffer_type)) {
[email protected]c62ce3e2009-02-26 00:15:20138 std::string text;
[email protected]0de5d8602011-11-22 03:48:52139 client_->ReadAsciiText(buffer_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20140 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36141 return ASCIIToUTF16(text);
[email protected]c62ce3e2009-02-26 00:15:20142 }
143
144 return WebString();
145}
146
[email protected]a96790b2011-10-06 22:24:10147WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url,
148 unsigned* fragment_start,
149 unsigned* fragment_end) {
150 ui::Clipboard::Buffer buffer_type;
151 if (!ConvertBufferType(buffer, &buffer_type))
152 return WebString();
153
[email protected]82758352013-03-29 19:21:31154 base::string16 html_stdstr;
[email protected]a96790b2011-10-06 22:24:10155 GURL gurl;
[email protected]0de5d8602011-11-22 03:48:52156 client_->ReadHTML(buffer_type, &html_stdstr, &gurl,
[email protected]a96790b2011-10-06 22:24:10157 static_cast<uint32*>(fragment_start),
158 static_cast<uint32*>(fragment_end));
[email protected]c62ce3e2009-02-26 00:15:20159 *source_url = gurl;
[email protected]3a2a5d22009-03-04 03:36:36160 return html_stdstr;
[email protected]c62ce3e2009-02-26 00:15:20161}
162
[email protected]3d4a6912011-03-15 20:56:19163WebData WebClipboardImpl::readImage(Buffer buffer) {
164 ui::Clipboard::Buffer buffer_type;
165 if (!ConvertBufferType(buffer, &buffer_type))
166 return WebData();
167
168 std::string png_data;
[email protected]0de5d8602011-11-22 03:48:52169 client_->ReadImage(buffer_type, &png_data);
[email protected]3d4a6912011-03-15 20:56:19170 return WebData(png_data);
171}
172
[email protected]c6562f42011-12-04 06:19:37173WebString WebClipboardImpl::readCustomData(Buffer buffer,
174 const WebString& type) {
175 ui::Clipboard::Buffer buffer_type;
176 if (!ConvertBufferType(buffer, &buffer_type))
177 return WebString();
178
[email protected]82758352013-03-29 19:21:31179 base::string16 data;
[email protected]c6562f42011-12-04 06:19:37180 client_->ReadCustomData(buffer_type, type, &data);
181 return data;
182}
183
[email protected]c62ce3e2009-02-26 00:15:20184void WebClipboardImpl::writeHTML(
185 const WebString& html_text, const WebURL& source_url,
186 const WebString& plain_text, bool write_smart_paste) {
[email protected]0de5d8602011-11-22 03:48:52187 ScopedClipboardWriterGlue scw(client_);
[email protected]3a2a5d22009-03-04 03:36:36188 scw.WriteHTML(html_text, source_url.spec());
189 scw.WriteText(plain_text);
[email protected]c62ce3e2009-02-26 00:15:20190
191 if (write_smart_paste)
192 scw.WriteWebSmartPaste();
193}
194
[email protected]8c95a752009-09-25 10:54:22195void WebClipboardImpl::writePlainText(const WebString& plain_text) {
[email protected]0de5d8602011-11-22 03:48:52196 ScopedClipboardWriterGlue scw(client_);
[email protected]8c95a752009-09-25 10:54:22197 scw.WriteText(plain_text);
198}
199
[email protected]c62ce3e2009-02-26 00:15:20200void WebClipboardImpl::writeURL(const WebURL& url, const WebString& title) {
[email protected]0de5d8602011-11-22 03:48:52201 ScopedClipboardWriterGlue scw(client_);
[email protected]c62ce3e2009-02-26 00:15:20202
[email protected]3a2a5d22009-03-04 03:36:36203 scw.WriteBookmark(title, url.spec());
204 scw.WriteHTML(UTF8ToUTF16(URLToMarkup(url, title)), "");
[email protected]39a749c2011-01-28 02:40:46205 scw.WriteText(UTF8ToUTF16(std::string(url.spec())));
[email protected]c62ce3e2009-02-26 00:15:20206}
207
208void WebClipboardImpl::writeImage(
209 const WebImage& image, const WebURL& url, const WebString& title) {
[email protected]0de5d8602011-11-22 03:48:52210 ScopedClipboardWriterGlue scw(client_);
[email protected]c62ce3e2009-02-26 00:15:20211
[email protected]8973f522009-07-03 05:58:45212 if (!image.isNull()) {
[email protected]8973f522009-07-03 05:58:45213 const SkBitmap& bitmap = image.getSkBitmap();
[email protected]8973f522009-07-03 05:58:45214 SkAutoLockPixels locked(bitmap);
215 scw.WriteBitmapFromPixels(bitmap.getPixels(), image.size());
216 }
[email protected]c62ce3e2009-02-26 00:15:20217
[email protected]59d9aacf2009-11-30 22:59:25218 if (!url.isEmpty()) {
219 scw.WriteBookmark(title, url.spec());
[email protected]09303232011-06-09 19:28:31220#if !defined(OS_MACOSX)
221 // When writing the image, we also write the image markup so that pasting
222 // into rich text editors, such as Gmail, reveals the image. We also don't
223 // want to call writeText(), since some applications (WordPad) don't pick
224 // the image if there is also a text format on the clipboard.
225 // We also don't want to write HTML on a Mac, since Mail.app prefers to use
226 // the image markup over attaching the actual image. See
227 // http://crbug.com/33016 for details.
[email protected]59d9aacf2009-11-30 22:59:25228 scw.WriteHTML(UTF8ToUTF16(URLToImageMarkup(url, title)), "");
[email protected]09303232011-06-09 19:28:31229#endif
[email protected]59d9aacf2009-11-30 22:59:25230 }
[email protected]c62ce3e2009-02-26 00:15:20231}
232
[email protected]3f0318292011-11-18 21:49:00233void WebClipboardImpl::writeDataObject(const WebDragData& data) {
[email protected]0de5d8602011-11-22 03:48:52234 ScopedClipboardWriterGlue scw(client_);
[email protected]3f0318292011-11-18 21:49:00235
[email protected]2ffbb482011-12-05 23:41:17236 WebDropData data_object(data);
[email protected]3f0318292011-11-18 21:49:00237 // TODO(dcheng): Properly support text/uri-list here.
[email protected]da41ae92012-06-16 01:28:17238 if (!data_object.text.is_null())
239 scw.WriteText(data_object.text.string());
240 if (!data_object.html.is_null())
241 scw.WriteHTML(data_object.html.string(), "");
[email protected]fbf75412012-01-07 01:26:52242 // If there is no custom data, avoid calling WritePickledData. This ensures
243 // that ScopedClipboardWriterGlue's dtor remains a no-op if the page didn't
244 // modify the DataTransfer object, which is important to avoid stomping on
245 // any clipboard contents written by extension functions such as
[email protected]a19258af2012-09-21 06:36:33246 // chrome.bookmarkManagerPrivate.copy.
[email protected]fbf75412012-01-07 01:26:52247 if (!data_object.custom_data.empty()) {
248 Pickle pickle;
249 ui::WriteCustomDataToPickle(data_object.custom_data, &pickle);
250 scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType());
251 }
[email protected]3f0318292011-11-18 21:49:00252}
253
[email protected]65a6150d2009-09-08 22:16:05254bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
[email protected]2dfeaf92011-01-10 21:08:21255 ui::Clipboard::Buffer* result) {
[email protected]65a6150d2009-09-08 22:16:05256 switch (buffer) {
257 case BufferStandard:
[email protected]2dfeaf92011-01-10 21:08:21258 *result = ui::Clipboard::BUFFER_STANDARD;
[email protected]65a6150d2009-09-08 22:16:05259 break;
260 case BufferSelection:
[email protected]264b3192012-08-10 21:56:46261#if defined(USE_X11)
262#if defined(OS_CHROMEOS)
263 // Chrome OS only supports the standard clipboard,
264 // but not the X selection clipboad.
265 return false;
266#else
[email protected]2dfeaf92011-01-10 21:08:21267 *result = ui::Clipboard::BUFFER_SELECTION;
[email protected]65a6150d2009-09-08 22:16:05268 break;
269#endif
[email protected]264b3192012-08-10 21:56:46270#endif
[email protected]65a6150d2009-09-08 22:16:05271 default:
272 NOTREACHED();
273 return false;
274 }
275 return true;
276}
277
[email protected]c62ce3e2009-02-26 00:15:20278} // namespace webkit_glue