blob: 3232eca826afb76514758a9fc9ccbf6584bd8cfd [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"
[email protected]f9866fa2013-10-02 16:30:4512#include "content/renderer/clipboard_utils.h"
[email protected]dc293a72013-07-01 11:11:2213#include "content/renderer/drop_data_builder.h"
[email protected]bb7538f2013-06-21 00:40:2814#include "content/renderer/scoped_clipboard_writer_glue.h"
[email protected]c10884462013-05-30 00:22:0915#include "third_party/WebKit/public/platform/WebData.h"
16#include "third_party/WebKit/public/platform/WebDragData.h"
17#include "third_party/WebKit/public/platform/WebImage.h"
18#include "third_party/WebKit/public/platform/WebSize.h"
19#include "third_party/WebKit/public/platform/WebString.h"
20#include "third_party/WebKit/public/platform/WebURL.h"
21#include "third_party/WebKit/public/platform/WebVector.h"
[email protected]8973f522009-07-03 05:58:4522#include "third_party/skia/include/core/SkBitmap.h"
[email protected]2dfeaf92011-01-10 21:08:2123#include "ui/base/clipboard/clipboard.h"
[email protected]2ffbb482011-12-05 23:41:1724#include "ui/base/clipboard/custom_data_helper.h"
[email protected]707e1c42013-07-09 21:18:5825#include "url/gurl.h"
[email protected]c62ce3e2009-02-26 00:15:2026#include "webkit/glue/webkit_glue.h"
[email protected]c62ce3e2009-02-26 00:15:2027
[email protected]180ef242013-11-07 06:50:4628using blink::WebClipboard;
29using blink::WebData;
30using blink::WebDragData;
31using blink::WebImage;
32using blink::WebString;
33using blink::WebURL;
34using blink::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]9cf12c32011-11-10 19:28:0745uint64 WebClipboardImpl::sequenceNumber(Buffer buffer) {
[email protected]d68334c2013-10-12 17:02:0346 ui::ClipboardType clipboard_type;
47 if (!ConvertBufferType(buffer, &clipboard_type))
[email protected]9cf12c32011-11-10 19:28:0748 return 0;
49
[email protected]d68334c2013-10-12 17:02:0350 return client_->GetSequenceNumber(clipboard_type);
[email protected]36780a12011-11-04 18:16:4451}
52
[email protected]65a6150d2009-09-08 22:16:0553bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
[email protected]d68334c2013-10-12 17:02:0354 ui::ClipboardType clipboard_type = ui::CLIPBOARD_TYPE_COPY_PASTE;
[email protected]c62ce3e2009-02-26 00:15:2055
[email protected]d68334c2013-10-12 17:02:0356 if (!ConvertBufferType(buffer, &clipboard_type))
[email protected]606876c2011-03-24 17:13:3857 return false;
58
[email protected]c62ce3e2009-02-26 00:15:2059 switch (format) {
[email protected]606876c2011-03-24 17:13:3860 case FormatPlainText:
[email protected]0de5d8602011-11-22 03:48:5261 return client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]d68334c2013-10-12 17:02:0362 clipboard_type) ||
[email protected]0de5d8602011-11-22 03:48:5263 client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]d68334c2013-10-12 17:02:0364 clipboard_type);
[email protected]c62ce3e2009-02-26 00:15:2065 case FormatHTML:
[email protected]ff53be62011-12-07 23:28:2966 return client_->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(),
[email protected]d68334c2013-10-12 17:02:0367 clipboard_type);
[email protected]c62ce3e2009-02-26 00:15:2068 case FormatSmartPaste:
[email protected]ff53be62011-12-07 23:28:2969 return client_->IsFormatAvailable(
[email protected]d68334c2013-10-12 17:02:0370 ui::Clipboard::GetWebKitSmartPasteFormatType(), clipboard_type);
[email protected]c62ce3e2009-02-26 00:15:2071 case FormatBookmark:
72#if defined(OS_WIN) || defined(OS_MACOSX)
[email protected]ff53be62011-12-07 23:28:2973 return client_->IsFormatAvailable(ui::Clipboard::GetUrlWFormatType(),
[email protected]d68334c2013-10-12 17:02:0374 clipboard_type);
[email protected]c62ce3e2009-02-26 00:15:2075#endif
76 default:
77 NOTREACHED();
[email protected]c62ce3e2009-02-26 00:15:2078 }
79
[email protected]ff53be62011-12-07 23:28:2980 return false;
[email protected]c62ce3e2009-02-26 00:15:2081}
82
[email protected]36780a12011-11-04 18:16:4483WebVector<WebString> WebClipboardImpl::readAvailableTypes(
84 Buffer buffer, bool* contains_filenames) {
[email protected]d68334c2013-10-12 17:02:0385 ui::ClipboardType clipboard_type;
[email protected]82758352013-03-29 19:21:3186 std::vector<base::string16> types;
[email protected]d68334c2013-10-12 17:02:0387 if (ConvertBufferType(buffer, &clipboard_type)) {
88 client_->ReadAvailableTypes(clipboard_type, &types, contains_filenames);
[email protected]36780a12011-11-04 18:16:4489 }
90 return types;
91}
92
[email protected]65a6150d2009-09-08 22:16:0593WebString WebClipboardImpl::readPlainText(Buffer buffer) {
[email protected]d68334c2013-10-12 17:02:0394 ui::ClipboardType clipboard_type;
95 if (!ConvertBufferType(buffer, &clipboard_type))
[email protected]65a6150d2009-09-08 22:16:0596 return WebString();
97
[email protected]0de5d8602011-11-22 03:48:5298 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]d68334c2013-10-12 17:02:0399 clipboard_type)) {
[email protected]82758352013-03-29 19:21:31100 base::string16 text;
[email protected]d68334c2013-10-12 17:02:03101 client_->ReadText(clipboard_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20102 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36103 return text;
[email protected]c62ce3e2009-02-26 00:15:20104 }
105
[email protected]0de5d8602011-11-22 03:48:52106 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]d68334c2013-10-12 17:02:03107 clipboard_type)) {
[email protected]c62ce3e2009-02-26 00:15:20108 std::string text;
[email protected]d68334c2013-10-12 17:02:03109 client_->ReadAsciiText(clipboard_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20110 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36111 return ASCIIToUTF16(text);
[email protected]c62ce3e2009-02-26 00:15:20112 }
113
114 return WebString();
115}
116
[email protected]a96790b2011-10-06 22:24:10117WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url,
118 unsigned* fragment_start,
119 unsigned* fragment_end) {
[email protected]d68334c2013-10-12 17:02:03120 ui::ClipboardType clipboard_type;
121 if (!ConvertBufferType(buffer, &clipboard_type))
[email protected]a96790b2011-10-06 22:24:10122 return WebString();
123
[email protected]82758352013-03-29 19:21:31124 base::string16 html_stdstr;
[email protected]a96790b2011-10-06 22:24:10125 GURL gurl;
[email protected]d68334c2013-10-12 17:02:03126 client_->ReadHTML(clipboard_type, &html_stdstr, &gurl,
[email protected]a96790b2011-10-06 22:24:10127 static_cast<uint32*>(fragment_start),
128 static_cast<uint32*>(fragment_end));
[email protected]c62ce3e2009-02-26 00:15:20129 *source_url = gurl;
[email protected]3a2a5d22009-03-04 03:36:36130 return html_stdstr;
[email protected]c62ce3e2009-02-26 00:15:20131}
132
[email protected]3d4a6912011-03-15 20:56:19133WebData WebClipboardImpl::readImage(Buffer buffer) {
[email protected]d68334c2013-10-12 17:02:03134 ui::ClipboardType clipboard_type;
135 if (!ConvertBufferType(buffer, &clipboard_type))
[email protected]3d4a6912011-03-15 20:56:19136 return WebData();
137
138 std::string png_data;
[email protected]d68334c2013-10-12 17:02:03139 client_->ReadImage(clipboard_type, &png_data);
[email protected]3d4a6912011-03-15 20:56:19140 return WebData(png_data);
141}
142
[email protected]c6562f42011-12-04 06:19:37143WebString WebClipboardImpl::readCustomData(Buffer buffer,
144 const WebString& type) {
[email protected]d68334c2013-10-12 17:02:03145 ui::ClipboardType clipboard_type;
146 if (!ConvertBufferType(buffer, &clipboard_type))
[email protected]c6562f42011-12-04 06:19:37147 return WebString();
148
[email protected]82758352013-03-29 19:21:31149 base::string16 data;
[email protected]d68334c2013-10-12 17:02:03150 client_->ReadCustomData(clipboard_type, type, &data);
[email protected]c6562f42011-12-04 06:19:37151 return data;
152}
153
[email protected]d9a0eae92013-10-25 16:38:55154void WebClipboardImpl::writePlainText(const WebString& plain_text) {
155 ScopedClipboardWriterGlue scw(client_);
156 scw.WriteText(plain_text);
157}
158
[email protected]c62ce3e2009-02-26 00:15:20159void WebClipboardImpl::writeHTML(
160 const WebString& html_text, const WebURL& source_url,
161 const WebString& plain_text, bool write_smart_paste) {
[email protected]0de5d8602011-11-22 03:48:52162 ScopedClipboardWriterGlue scw(client_);
[email protected]3a2a5d22009-03-04 03:36:36163 scw.WriteHTML(html_text, source_url.spec());
164 scw.WriteText(plain_text);
[email protected]c62ce3e2009-02-26 00:15:20165
166 if (write_smart_paste)
167 scw.WriteWebSmartPaste();
168}
169
[email protected]f9866fa2013-10-02 16:30:45170void WebClipboardImpl::writeImage(const WebImage& image,
171 const WebURL& url,
172 const WebString& title) {
[email protected]0de5d8602011-11-22 03:48:52173 ScopedClipboardWriterGlue scw(client_);
[email protected]c62ce3e2009-02-26 00:15:20174
[email protected]8973f522009-07-03 05:58:45175 if (!image.isNull()) {
[email protected]8973f522009-07-03 05:58:45176 const SkBitmap& bitmap = image.getSkBitmap();
[email protected]8973f522009-07-03 05:58:45177 SkAutoLockPixels locked(bitmap);
178 scw.WriteBitmapFromPixels(bitmap.getPixels(), image.size());
179 }
[email protected]c62ce3e2009-02-26 00:15:20180
[email protected]59d9aacf2009-11-30 22:59:25181 if (!url.isEmpty()) {
182 scw.WriteBookmark(title, url.spec());
[email protected]09303232011-06-09 19:28:31183#if !defined(OS_MACOSX)
184 // When writing the image, we also write the image markup so that pasting
185 // into rich text editors, such as Gmail, reveals the image. We also don't
186 // want to call writeText(), since some applications (WordPad) don't pick
187 // the image if there is also a text format on the clipboard.
188 // We also don't want to write HTML on a Mac, since Mail.app prefers to use
189 // the image markup over attaching the actual image. See
190 // http://crbug.com/33016 for details.
[email protected]f9866fa2013-10-02 16:30:45191 scw.WriteHTML(UTF8ToUTF16(URLToImageMarkup(url, title)), std::string());
[email protected]09303232011-06-09 19:28:31192#endif
[email protected]59d9aacf2009-11-30 22:59:25193 }
[email protected]c62ce3e2009-02-26 00:15:20194}
195
[email protected]3f0318292011-11-18 21:49:00196void WebClipboardImpl::writeDataObject(const WebDragData& data) {
[email protected]0de5d8602011-11-22 03:48:52197 ScopedClipboardWriterGlue scw(client_);
[email protected]3f0318292011-11-18 21:49:00198
[email protected]dc293a72013-07-01 11:11:22199 const DropData& data_object = DropDataBuilder::Build(data);
[email protected]3f0318292011-11-18 21:49:00200 // TODO(dcheng): Properly support text/uri-list here.
[email protected]da41ae92012-06-16 01:28:17201 if (!data_object.text.is_null())
202 scw.WriteText(data_object.text.string());
203 if (!data_object.html.is_null())
[email protected]007b3f82013-04-09 08:46:45204 scw.WriteHTML(data_object.html.string(), std::string());
[email protected]fbf75412012-01-07 01:26:52205 // If there is no custom data, avoid calling WritePickledData. This ensures
206 // that ScopedClipboardWriterGlue's dtor remains a no-op if the page didn't
207 // modify the DataTransfer object, which is important to avoid stomping on
208 // any clipboard contents written by extension functions such as
[email protected]a19258af2012-09-21 06:36:33209 // chrome.bookmarkManagerPrivate.copy.
[email protected]fbf75412012-01-07 01:26:52210 if (!data_object.custom_data.empty()) {
211 Pickle pickle;
212 ui::WriteCustomDataToPickle(data_object.custom_data, &pickle);
213 scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType());
214 }
[email protected]3f0318292011-11-18 21:49:00215}
216
[email protected]65a6150d2009-09-08 22:16:05217bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
[email protected]d68334c2013-10-12 17:02:03218 ui::ClipboardType* result) {
219 *result = ui::CLIPBOARD_TYPE_COPY_PASTE;
[email protected]65a6150d2009-09-08 22:16:05220 switch (buffer) {
221 case BufferStandard:
[email protected]65a6150d2009-09-08 22:16:05222 break;
223 case BufferSelection:
[email protected]264b3192012-08-10 21:56:46224#if defined(USE_X11)
225#if defined(OS_CHROMEOS)
226 // Chrome OS only supports the standard clipboard,
227 // but not the X selection clipboad.
228 return false;
229#else
[email protected]d68334c2013-10-12 17:02:03230 *result = ui::CLIPBOARD_TYPE_SELECTION;
[email protected]65a6150d2009-09-08 22:16:05231 break;
232#endif
[email protected]264b3192012-08-10 21:56:46233#endif
[email protected]65a6150d2009-09-08 22:16:05234 default:
235 NOTREACHED();
236 return false;
237 }
238 return true;
239}
240
[email protected]bb7538f2013-06-21 00:40:28241} // namespace content