blob: 7aab1f07df9fd4cc5e31fce405870013225811ce [file] [log] [blame]
[email protected]bb7538f2013-06-21 00:40:281// Copyright (c) 2013 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]bb7538f2013-06-21 00:40:285#include "content/renderer/webclipboard_impl.h"
[email protected]c62ce3e2009-02-26 00:15:206
[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]e464fee2013-06-11 12:42:209#include "base/strings/string_util.h"
[email protected]906265872013-06-07 22:40:4510#include "base/strings/utf_string_conversions.h"
[email protected]dc293a72013-07-01 11:11:2211#include "content/public/common/drop_data.h"
12#include "content/renderer/drop_data_builder.h"
[email protected]bb7538f2013-06-21 00:40:2813#include "content/renderer/scoped_clipboard_writer_glue.h"
[email protected]c10884462013-05-30 00:22:0914#include "third_party/WebKit/public/platform/WebData.h"
15#include "third_party/WebKit/public/platform/WebDragData.h"
16#include "third_party/WebKit/public/platform/WebImage.h"
17#include "third_party/WebKit/public/platform/WebSize.h"
18#include "third_party/WebKit/public/platform/WebString.h"
19#include "third_party/WebKit/public/platform/WebURL.h"
20#include "third_party/WebKit/public/platform/WebVector.h"
[email protected]8973f522009-07-03 05:58:4521#include "third_party/skia/include/core/SkBitmap.h"
[email protected]2dfeaf92011-01-10 21:08:2122#include "ui/base/clipboard/clipboard.h"
[email protected]2ffbb482011-12-05 23:41:1723#include "ui/base/clipboard/custom_data_helper.h"
[email protected]707e1c42013-07-09 21:18:5824#include "url/gurl.h"
[email protected]c62ce3e2009-02-26 00:15:2025#include "webkit/glue/webkit_glue.h"
[email protected]bb7538f2013-06-21 00:40:2826#include "webkit/renderer/clipboard_utils.h"
[email protected]c62ce3e2009-02-26 00:15:2027
28using WebKit::WebClipboard;
[email protected]3d4a6912011-03-15 20:56:1929using WebKit::WebData;
[email protected]3f0318292011-11-18 21:49:0030using WebKit::WebDragData;
[email protected]c62ce3e2009-02-26 00:15:2031using WebKit::WebImage;
32using WebKit::WebString;
33using WebKit::WebURL;
[email protected]97c2c032010-07-07 22:43:4134using WebKit::WebVector;
[email protected]c62ce3e2009-02-26 00:15:2035
[email protected]bb7538f2013-06-21 00:40:2836namespace content {
[email protected]c62ce3e2009-02-26 00:15:2037
[email protected]0de5d8602011-11-22 03:48:5238WebClipboardImpl::WebClipboardImpl(ClipboardClient* client)
39 : client_(client) {
40}
41
[email protected]04bf3ad2010-08-27 21:23:4842WebClipboardImpl::~WebClipboardImpl() {
43}
44
[email protected]36780a12011-11-04 18:16:4445uint64 WebClipboardImpl::getSequenceNumber() {
[email protected]9cf12c32011-11-10 19:28:0746 return sequenceNumber(BufferStandard);
47}
48
49uint64 WebClipboardImpl::sequenceNumber(Buffer buffer) {
50 ui::Clipboard::Buffer buffer_type;
51 if (!ConvertBufferType(buffer, &buffer_type))
52 return 0;
53
[email protected]0de5d8602011-11-22 03:48:5254 return client_->GetSequenceNumber(buffer_type);
[email protected]36780a12011-11-04 18:16:4455}
56
[email protected]65a6150d2009-09-08 22:16:0557bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
[email protected]757d4e542012-01-20 22:23:4258 ui::Clipboard::Buffer buffer_type = ui::Clipboard::BUFFER_STANDARD;
[email protected]c62ce3e2009-02-26 00:15:2059
[email protected]606876c2011-03-24 17:13:3860 if (!ConvertBufferType(buffer, &buffer_type))
61 return false;
62
[email protected]c62ce3e2009-02-26 00:15:2063 switch (format) {
[email protected]606876c2011-03-24 17:13:3864 case FormatPlainText:
[email protected]0de5d8602011-11-22 03:48:5265 return client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]606876c2011-03-24 17:13:3866 buffer_type) ||
[email protected]0de5d8602011-11-22 03:48:5267 client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]606876c2011-03-24 17:13:3868 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2069 case FormatHTML:
[email protected]ff53be62011-12-07 23:28:2970 return client_->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(),
71 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2072 case FormatSmartPaste:
[email protected]ff53be62011-12-07 23:28:2973 return client_->IsFormatAvailable(
74 ui::Clipboard::GetWebKitSmartPasteFormatType(), buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2075 case FormatBookmark:
76#if defined(OS_WIN) || defined(OS_MACOSX)
[email protected]ff53be62011-12-07 23:28:2977 return client_->IsFormatAvailable(ui::Clipboard::GetUrlWFormatType(),
78 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2079#endif
80 default:
81 NOTREACHED();
[email protected]c62ce3e2009-02-26 00:15:2082 }
83
[email protected]ff53be62011-12-07 23:28:2984 return false;
[email protected]c62ce3e2009-02-26 00:15:2085}
86
[email protected]36780a12011-11-04 18:16:4487WebVector<WebString> WebClipboardImpl::readAvailableTypes(
88 Buffer buffer, bool* contains_filenames) {
89 ui::Clipboard::Buffer buffer_type;
[email protected]82758352013-03-29 19:21:3190 std::vector<base::string16> types;
[email protected]36780a12011-11-04 18:16:4491 if (ConvertBufferType(buffer, &buffer_type)) {
[email protected]0de5d8602011-11-22 03:48:5292 client_->ReadAvailableTypes(buffer_type, &types, contains_filenames);
[email protected]36780a12011-11-04 18:16:4493 }
94 return types;
95}
96
[email protected]65a6150d2009-09-08 22:16:0597WebString WebClipboardImpl::readPlainText(Buffer buffer) {
[email protected]2dfeaf92011-01-10 21:08:2198 ui::Clipboard::Buffer buffer_type;
[email protected]65a6150d2009-09-08 22:16:0599 if (!ConvertBufferType(buffer, &buffer_type))
100 return WebString();
101
[email protected]0de5d8602011-11-22 03:48:52102 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]65a6150d2009-09-08 22:16:05103 buffer_type)) {
[email protected]82758352013-03-29 19:21:31104 base::string16 text;
[email protected]0de5d8602011-11-22 03:48:52105 client_->ReadText(buffer_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20106 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36107 return text;
[email protected]c62ce3e2009-02-26 00:15:20108 }
109
[email protected]0de5d8602011-11-22 03:48:52110 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]65a6150d2009-09-08 22:16:05111 buffer_type)) {
[email protected]c62ce3e2009-02-26 00:15:20112 std::string text;
[email protected]0de5d8602011-11-22 03:48:52113 client_->ReadAsciiText(buffer_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20114 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36115 return ASCIIToUTF16(text);
[email protected]c62ce3e2009-02-26 00:15:20116 }
117
118 return WebString();
119}
120
[email protected]a96790b2011-10-06 22:24:10121WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url,
122 unsigned* fragment_start,
123 unsigned* fragment_end) {
124 ui::Clipboard::Buffer buffer_type;
125 if (!ConvertBufferType(buffer, &buffer_type))
126 return WebString();
127
[email protected]82758352013-03-29 19:21:31128 base::string16 html_stdstr;
[email protected]a96790b2011-10-06 22:24:10129 GURL gurl;
[email protected]0de5d8602011-11-22 03:48:52130 client_->ReadHTML(buffer_type, &html_stdstr, &gurl,
[email protected]a96790b2011-10-06 22:24:10131 static_cast<uint32*>(fragment_start),
132 static_cast<uint32*>(fragment_end));
[email protected]c62ce3e2009-02-26 00:15:20133 *source_url = gurl;
[email protected]3a2a5d22009-03-04 03:36:36134 return html_stdstr;
[email protected]c62ce3e2009-02-26 00:15:20135}
136
[email protected]3d4a6912011-03-15 20:56:19137WebData WebClipboardImpl::readImage(Buffer buffer) {
138 ui::Clipboard::Buffer buffer_type;
139 if (!ConvertBufferType(buffer, &buffer_type))
140 return WebData();
141
142 std::string png_data;
[email protected]0de5d8602011-11-22 03:48:52143 client_->ReadImage(buffer_type, &png_data);
[email protected]3d4a6912011-03-15 20:56:19144 return WebData(png_data);
145}
146
[email protected]c6562f42011-12-04 06:19:37147WebString WebClipboardImpl::readCustomData(Buffer buffer,
148 const WebString& type) {
149 ui::Clipboard::Buffer buffer_type;
150 if (!ConvertBufferType(buffer, &buffer_type))
151 return WebString();
152
[email protected]82758352013-03-29 19:21:31153 base::string16 data;
[email protected]c6562f42011-12-04 06:19:37154 client_->ReadCustomData(buffer_type, type, &data);
155 return data;
156}
157
[email protected]c62ce3e2009-02-26 00:15:20158void WebClipboardImpl::writeHTML(
159 const WebString& html_text, const WebURL& source_url,
160 const WebString& plain_text, bool write_smart_paste) {
[email protected]0de5d8602011-11-22 03:48:52161 ScopedClipboardWriterGlue scw(client_);
[email protected]3a2a5d22009-03-04 03:36:36162 scw.WriteHTML(html_text, source_url.spec());
163 scw.WriteText(plain_text);
[email protected]c62ce3e2009-02-26 00:15:20164
165 if (write_smart_paste)
166 scw.WriteWebSmartPaste();
167}
168
[email protected]8c95a752009-09-25 10:54:22169void WebClipboardImpl::writePlainText(const WebString& plain_text) {
[email protected]0de5d8602011-11-22 03:48:52170 ScopedClipboardWriterGlue scw(client_);
[email protected]8c95a752009-09-25 10:54:22171 scw.WriteText(plain_text);
172}
173
[email protected]c62ce3e2009-02-26 00:15:20174void WebClipboardImpl::writeURL(const WebURL& url, const WebString& title) {
[email protected]0de5d8602011-11-22 03:48:52175 ScopedClipboardWriterGlue scw(client_);
[email protected]c62ce3e2009-02-26 00:15:20176
[email protected]3a2a5d22009-03-04 03:36:36177 scw.WriteBookmark(title, url.spec());
[email protected]bb7538f2013-06-21 00:40:28178 scw.WriteHTML(UTF8ToUTF16(webkit_clipboard::URLToMarkup(url, title)),
179 std::string());
[email protected]39a749c2011-01-28 02:40:46180 scw.WriteText(UTF8ToUTF16(std::string(url.spec())));
[email protected]c62ce3e2009-02-26 00:15:20181}
182
183void WebClipboardImpl::writeImage(
184 const WebImage& image, const WebURL& url, const WebString& title) {
[email protected]0de5d8602011-11-22 03:48:52185 ScopedClipboardWriterGlue scw(client_);
[email protected]c62ce3e2009-02-26 00:15:20186
[email protected]8973f522009-07-03 05:58:45187 if (!image.isNull()) {
[email protected]8973f522009-07-03 05:58:45188 const SkBitmap& bitmap = image.getSkBitmap();
[email protected]8973f522009-07-03 05:58:45189 SkAutoLockPixels locked(bitmap);
190 scw.WriteBitmapFromPixels(bitmap.getPixels(), image.size());
191 }
[email protected]c62ce3e2009-02-26 00:15:20192
[email protected]59d9aacf2009-11-30 22:59:25193 if (!url.isEmpty()) {
194 scw.WriteBookmark(title, url.spec());
[email protected]09303232011-06-09 19:28:31195#if !defined(OS_MACOSX)
196 // When writing the image, we also write the image markup so that pasting
197 // into rich text editors, such as Gmail, reveals the image. We also don't
198 // want to call writeText(), since some applications (WordPad) don't pick
199 // the image if there is also a text format on the clipboard.
200 // We also don't want to write HTML on a Mac, since Mail.app prefers to use
201 // the image markup over attaching the actual image. See
202 // http://crbug.com/33016 for details.
[email protected]bb7538f2013-06-21 00:40:28203 scw.WriteHTML(UTF8ToUTF16(webkit_clipboard::URLToImageMarkup(url, title)),
204 std::string());
[email protected]09303232011-06-09 19:28:31205#endif
[email protected]59d9aacf2009-11-30 22:59:25206 }
[email protected]c62ce3e2009-02-26 00:15:20207}
208
[email protected]3f0318292011-11-18 21:49:00209void WebClipboardImpl::writeDataObject(const WebDragData& data) {
[email protected]0de5d8602011-11-22 03:48:52210 ScopedClipboardWriterGlue scw(client_);
[email protected]3f0318292011-11-18 21:49:00211
[email protected]dc293a72013-07-01 11:11:22212 const DropData& data_object = DropDataBuilder::Build(data);
[email protected]3f0318292011-11-18 21:49:00213 // TODO(dcheng): Properly support text/uri-list here.
[email protected]da41ae92012-06-16 01:28:17214 if (!data_object.text.is_null())
215 scw.WriteText(data_object.text.string());
216 if (!data_object.html.is_null())
[email protected]007b3f82013-04-09 08:46:45217 scw.WriteHTML(data_object.html.string(), std::string());
[email protected]fbf75412012-01-07 01:26:52218 // If there is no custom data, avoid calling WritePickledData. This ensures
219 // that ScopedClipboardWriterGlue's dtor remains a no-op if the page didn't
220 // modify the DataTransfer object, which is important to avoid stomping on
221 // any clipboard contents written by extension functions such as
[email protected]a19258af2012-09-21 06:36:33222 // chrome.bookmarkManagerPrivate.copy.
[email protected]fbf75412012-01-07 01:26:52223 if (!data_object.custom_data.empty()) {
224 Pickle pickle;
225 ui::WriteCustomDataToPickle(data_object.custom_data, &pickle);
226 scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType());
227 }
[email protected]3f0318292011-11-18 21:49:00228}
229
[email protected]65a6150d2009-09-08 22:16:05230bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
[email protected]2dfeaf92011-01-10 21:08:21231 ui::Clipboard::Buffer* result) {
[email protected]65a6150d2009-09-08 22:16:05232 switch (buffer) {
233 case BufferStandard:
[email protected]2dfeaf92011-01-10 21:08:21234 *result = ui::Clipboard::BUFFER_STANDARD;
[email protected]65a6150d2009-09-08 22:16:05235 break;
236 case BufferSelection:
[email protected]264b3192012-08-10 21:56:46237#if defined(USE_X11)
238#if defined(OS_CHROMEOS)
239 // Chrome OS only supports the standard clipboard,
240 // but not the X selection clipboad.
241 return false;
242#else
[email protected]2dfeaf92011-01-10 21:08:21243 *result = ui::Clipboard::BUFFER_SELECTION;
[email protected]65a6150d2009-09-08 22:16:05244 break;
245#endif
[email protected]264b3192012-08-10 21:56:46246#endif
[email protected]65a6150d2009-09-08 22:16:05247 default:
248 NOTREACHED();
249 return false;
250 }
251 return true;
252}
253
[email protected]bb7538f2013-06-21 00:40:28254} // namespace content
255