blob: 7ba388d6ee7c3382291e0ad652f98ed5b4f25098 [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]bb7538f2013-06-21 00:40:2811#include "content/renderer/scoped_clipboard_writer_glue.h"
[email protected]c62ce3e2009-02-26 00:15:2012#include "googleurl/src/gurl.h"
[email protected]c10884462013-05-30 00:22:0913#include "third_party/WebKit/public/platform/WebData.h"
14#include "third_party/WebKit/public/platform/WebDragData.h"
15#include "third_party/WebKit/public/platform/WebImage.h"
16#include "third_party/WebKit/public/platform/WebSize.h"
17#include "third_party/WebKit/public/platform/WebString.h"
18#include "third_party/WebKit/public/platform/WebURL.h"
19#include "third_party/WebKit/public/platform/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]c10680312013-05-31 15:22:0523#include "webkit/common/webdropdata.h"
[email protected]c62ce3e2009-02-26 00:15:2024#include "webkit/glue/webkit_glue.h"
[email protected]bb7538f2013-06-21 00:40:2825#include "webkit/renderer/clipboard_utils.h"
[email protected]c62ce3e2009-02-26 00:15:2026
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
[email protected]bb7538f2013-06-21 00:40:2835namespace content {
[email protected]c62ce3e2009-02-26 00:15:2036
[email protected]0de5d8602011-11-22 03:48:5237WebClipboardImpl::WebClipboardImpl(ClipboardClient* client)
38 : client_(client) {
39}
40
[email protected]04bf3ad2010-08-27 21:23:4841WebClipboardImpl::~WebClipboardImpl() {
42}
43
[email protected]36780a12011-11-04 18:16:4444uint64 WebClipboardImpl::getSequenceNumber() {
[email protected]9cf12c32011-11-10 19:28:0745 return sequenceNumber(BufferStandard);
46}
47
48uint64 WebClipboardImpl::sequenceNumber(Buffer buffer) {
49 ui::Clipboard::Buffer buffer_type;
50 if (!ConvertBufferType(buffer, &buffer_type))
51 return 0;
52
[email protected]0de5d8602011-11-22 03:48:5253 return client_->GetSequenceNumber(buffer_type);
[email protected]36780a12011-11-04 18:16:4454}
55
[email protected]65a6150d2009-09-08 22:16:0556bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
[email protected]757d4e542012-01-20 22:23:4257 ui::Clipboard::Buffer buffer_type = ui::Clipboard::BUFFER_STANDARD;
[email protected]c62ce3e2009-02-26 00:15:2058
[email protected]606876c2011-03-24 17:13:3859 if (!ConvertBufferType(buffer, &buffer_type))
60 return false;
61
[email protected]c62ce3e2009-02-26 00:15:2062 switch (format) {
[email protected]606876c2011-03-24 17:13:3863 case FormatPlainText:
[email protected]0de5d8602011-11-22 03:48:5264 return client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]606876c2011-03-24 17:13:3865 buffer_type) ||
[email protected]0de5d8602011-11-22 03:48:5266 client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]606876c2011-03-24 17:13:3867 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2068 case FormatHTML:
[email protected]ff53be62011-12-07 23:28:2969 return client_->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(),
70 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2071 case FormatSmartPaste:
[email protected]ff53be62011-12-07 23:28:2972 return client_->IsFormatAvailable(
73 ui::Clipboard::GetWebKitSmartPasteFormatType(), buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2074 case FormatBookmark:
75#if defined(OS_WIN) || defined(OS_MACOSX)
[email protected]ff53be62011-12-07 23:28:2976 return client_->IsFormatAvailable(ui::Clipboard::GetUrlWFormatType(),
77 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:2078#endif
79 default:
80 NOTREACHED();
[email protected]c62ce3e2009-02-26 00:15:2081 }
82
[email protected]ff53be62011-12-07 23:28:2983 return false;
[email protected]c62ce3e2009-02-26 00:15:2084}
85
[email protected]36780a12011-11-04 18:16:4486WebVector<WebString> WebClipboardImpl::readAvailableTypes(
87 Buffer buffer, bool* contains_filenames) {
88 ui::Clipboard::Buffer buffer_type;
[email protected]82758352013-03-29 19:21:3189 std::vector<base::string16> types;
[email protected]36780a12011-11-04 18:16:4490 if (ConvertBufferType(buffer, &buffer_type)) {
[email protected]0de5d8602011-11-22 03:48:5291 client_->ReadAvailableTypes(buffer_type, &types, contains_filenames);
[email protected]36780a12011-11-04 18:16:4492 }
93 return types;
94}
95
[email protected]65a6150d2009-09-08 22:16:0596WebString WebClipboardImpl::readPlainText(Buffer buffer) {
[email protected]2dfeaf92011-01-10 21:08:2197 ui::Clipboard::Buffer buffer_type;
[email protected]65a6150d2009-09-08 22:16:0598 if (!ConvertBufferType(buffer, &buffer_type))
99 return WebString();
100
[email protected]0de5d8602011-11-22 03:48:52101 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]65a6150d2009-09-08 22:16:05102 buffer_type)) {
[email protected]82758352013-03-29 19:21:31103 base::string16 text;
[email protected]0de5d8602011-11-22 03:48:52104 client_->ReadText(buffer_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20105 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36106 return text;
[email protected]c62ce3e2009-02-26 00:15:20107 }
108
[email protected]0de5d8602011-11-22 03:48:52109 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]65a6150d2009-09-08 22:16:05110 buffer_type)) {
[email protected]c62ce3e2009-02-26 00:15:20111 std::string text;
[email protected]0de5d8602011-11-22 03:48:52112 client_->ReadAsciiText(buffer_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20113 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36114 return ASCIIToUTF16(text);
[email protected]c62ce3e2009-02-26 00:15:20115 }
116
117 return WebString();
118}
119
[email protected]a96790b2011-10-06 22:24:10120WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url,
121 unsigned* fragment_start,
122 unsigned* fragment_end) {
123 ui::Clipboard::Buffer buffer_type;
124 if (!ConvertBufferType(buffer, &buffer_type))
125 return WebString();
126
[email protected]82758352013-03-29 19:21:31127 base::string16 html_stdstr;
[email protected]a96790b2011-10-06 22:24:10128 GURL gurl;
[email protected]0de5d8602011-11-22 03:48:52129 client_->ReadHTML(buffer_type, &html_stdstr, &gurl,
[email protected]a96790b2011-10-06 22:24:10130 static_cast<uint32*>(fragment_start),
131 static_cast<uint32*>(fragment_end));
[email protected]c62ce3e2009-02-26 00:15:20132 *source_url = gurl;
[email protected]3a2a5d22009-03-04 03:36:36133 return html_stdstr;
[email protected]c62ce3e2009-02-26 00:15:20134}
135
[email protected]3d4a6912011-03-15 20:56:19136WebData WebClipboardImpl::readImage(Buffer buffer) {
137 ui::Clipboard::Buffer buffer_type;
138 if (!ConvertBufferType(buffer, &buffer_type))
139 return WebData();
140
141 std::string png_data;
[email protected]0de5d8602011-11-22 03:48:52142 client_->ReadImage(buffer_type, &png_data);
[email protected]3d4a6912011-03-15 20:56:19143 return WebData(png_data);
144}
145
[email protected]c6562f42011-12-04 06:19:37146WebString WebClipboardImpl::readCustomData(Buffer buffer,
147 const WebString& type) {
148 ui::Clipboard::Buffer buffer_type;
149 if (!ConvertBufferType(buffer, &buffer_type))
150 return WebString();
151
[email protected]82758352013-03-29 19:21:31152 base::string16 data;
[email protected]c6562f42011-12-04 06:19:37153 client_->ReadCustomData(buffer_type, type, &data);
154 return data;
155}
156
[email protected]c62ce3e2009-02-26 00:15:20157void WebClipboardImpl::writeHTML(
158 const WebString& html_text, const WebURL& source_url,
159 const WebString& plain_text, bool write_smart_paste) {
[email protected]0de5d8602011-11-22 03:48:52160 ScopedClipboardWriterGlue scw(client_);
[email protected]3a2a5d22009-03-04 03:36:36161 scw.WriteHTML(html_text, source_url.spec());
162 scw.WriteText(plain_text);
[email protected]c62ce3e2009-02-26 00:15:20163
164 if (write_smart_paste)
165 scw.WriteWebSmartPaste();
166}
167
[email protected]8c95a752009-09-25 10:54:22168void WebClipboardImpl::writePlainText(const WebString& plain_text) {
[email protected]0de5d8602011-11-22 03:48:52169 ScopedClipboardWriterGlue scw(client_);
[email protected]8c95a752009-09-25 10:54:22170 scw.WriteText(plain_text);
171}
172
[email protected]c62ce3e2009-02-26 00:15:20173void WebClipboardImpl::writeURL(const WebURL& url, const WebString& title) {
[email protected]0de5d8602011-11-22 03:48:52174 ScopedClipboardWriterGlue scw(client_);
[email protected]c62ce3e2009-02-26 00:15:20175
[email protected]3a2a5d22009-03-04 03:36:36176 scw.WriteBookmark(title, url.spec());
[email protected]bb7538f2013-06-21 00:40:28177 scw.WriteHTML(UTF8ToUTF16(webkit_clipboard::URLToMarkup(url, title)),
178 std::string());
[email protected]39a749c2011-01-28 02:40:46179 scw.WriteText(UTF8ToUTF16(std::string(url.spec())));
[email protected]c62ce3e2009-02-26 00:15:20180}
181
182void WebClipboardImpl::writeImage(
183 const WebImage& image, const WebURL& url, const WebString& title) {
[email protected]0de5d8602011-11-22 03:48:52184 ScopedClipboardWriterGlue scw(client_);
[email protected]c62ce3e2009-02-26 00:15:20185
[email protected]8973f522009-07-03 05:58:45186 if (!image.isNull()) {
[email protected]8973f522009-07-03 05:58:45187 const SkBitmap& bitmap = image.getSkBitmap();
[email protected]8973f522009-07-03 05:58:45188 SkAutoLockPixels locked(bitmap);
189 scw.WriteBitmapFromPixels(bitmap.getPixels(), image.size());
190 }
[email protected]c62ce3e2009-02-26 00:15:20191
[email protected]59d9aacf2009-11-30 22:59:25192 if (!url.isEmpty()) {
193 scw.WriteBookmark(title, url.spec());
[email protected]09303232011-06-09 19:28:31194#if !defined(OS_MACOSX)
195 // When writing the image, we also write the image markup so that pasting
196 // into rich text editors, such as Gmail, reveals the image. We also don't
197 // want to call writeText(), since some applications (WordPad) don't pick
198 // the image if there is also a text format on the clipboard.
199 // We also don't want to write HTML on a Mac, since Mail.app prefers to use
200 // the image markup over attaching the actual image. See
201 // http://crbug.com/33016 for details.
[email protected]bb7538f2013-06-21 00:40:28202 scw.WriteHTML(UTF8ToUTF16(webkit_clipboard::URLToImageMarkup(url, title)),
203 std::string());
[email protected]09303232011-06-09 19:28:31204#endif
[email protected]59d9aacf2009-11-30 22:59:25205 }
[email protected]c62ce3e2009-02-26 00:15:20206}
207
[email protected]3f0318292011-11-18 21:49:00208void WebClipboardImpl::writeDataObject(const WebDragData& data) {
[email protected]0de5d8602011-11-22 03:48:52209 ScopedClipboardWriterGlue scw(client_);
[email protected]3f0318292011-11-18 21:49:00210
[email protected]2ffbb482011-12-05 23:41:17211 WebDropData data_object(data);
[email protected]3f0318292011-11-18 21:49:00212 // TODO(dcheng): Properly support text/uri-list here.
[email protected]da41ae92012-06-16 01:28:17213 if (!data_object.text.is_null())
214 scw.WriteText(data_object.text.string());
215 if (!data_object.html.is_null())
[email protected]007b3f82013-04-09 08:46:45216 scw.WriteHTML(data_object.html.string(), std::string());
[email protected]fbf75412012-01-07 01:26:52217 // If there is no custom data, avoid calling WritePickledData. This ensures
218 // that ScopedClipboardWriterGlue's dtor remains a no-op if the page didn't
219 // modify the DataTransfer object, which is important to avoid stomping on
220 // any clipboard contents written by extension functions such as
[email protected]a19258af2012-09-21 06:36:33221 // chrome.bookmarkManagerPrivate.copy.
[email protected]fbf75412012-01-07 01:26:52222 if (!data_object.custom_data.empty()) {
223 Pickle pickle;
224 ui::WriteCustomDataToPickle(data_object.custom_data, &pickle);
225 scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType());
226 }
[email protected]3f0318292011-11-18 21:49:00227}
228
[email protected]65a6150d2009-09-08 22:16:05229bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
[email protected]2dfeaf92011-01-10 21:08:21230 ui::Clipboard::Buffer* result) {
[email protected]65a6150d2009-09-08 22:16:05231 switch (buffer) {
232 case BufferStandard:
[email protected]2dfeaf92011-01-10 21:08:21233 *result = ui::Clipboard::BUFFER_STANDARD;
[email protected]65a6150d2009-09-08 22:16:05234 break;
235 case BufferSelection:
[email protected]264b3192012-08-10 21:56:46236#if defined(USE_X11)
237#if defined(OS_CHROMEOS)
238 // Chrome OS only supports the standard clipboard,
239 // but not the X selection clipboad.
240 return false;
241#else
[email protected]2dfeaf92011-01-10 21:08:21242 *result = ui::Clipboard::BUFFER_SELECTION;
[email protected]65a6150d2009-09-08 22:16:05243 break;
244#endif
[email protected]264b3192012-08-10 21:56:46245#endif
[email protected]65a6150d2009-09-08 22:16:05246 default:
247 NOTREACHED();
248 return false;
249 }
250 return true;
251}
252
[email protected]bb7538f2013-06-21 00:40:28253} // namespace content
254