blob: 000fea18899280e181656b64f57e1a871bd73acf [file] [log] [blame]
[email protected]2dfeaf92011-01-10 21:08:211// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// 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]8973f522009-07-03 05:58:4513#include "third_party/skia/include/core/SkBitmap.h"
[email protected]3034b6812011-12-03 00:00:1414#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h"
15#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebDragData.h"
16#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebImage.h"
17#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
18#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
19#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
20#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.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
[email protected]8973f522009-07-03 05:58:4527#if WEBKIT_USING_CG
28#include "skia/ext/skia_utils_mac.h"
29#endif
30
[email protected]c62ce3e2009-02-26 00:15:2031using WebKit::WebClipboard;
[email protected]3d4a6912011-03-15 20:56:1932using WebKit::WebData;
[email protected]3f0318292011-11-18 21:49:0033using WebKit::WebDragData;
[email protected]c62ce3e2009-02-26 00:15:2034using WebKit::WebImage;
35using WebKit::WebString;
36using WebKit::WebURL;
[email protected]97c2c032010-07-07 22:43:4137using WebKit::WebVector;
[email protected]c62ce3e2009-02-26 00:15:2038
39namespace webkit_glue {
40
[email protected]b9a0b1b32009-03-30 23:09:3741// Static
42std::string WebClipboardImpl::URLToMarkup(const WebURL& url,
43 const WebString& title) {
[email protected]c62ce3e2009-02-26 00:15:2044 std::string markup("<a href=\"");
45 markup.append(url.spec());
46 markup.append("\">");
47 // TODO(darin): HTML escape this
[email protected]a0200c52011-10-13 14:19:2748 markup.append(net::EscapeForHTML(UTF16ToUTF8(title)));
[email protected]c62ce3e2009-02-26 00:15:2049 markup.append("</a>");
50 return markup;
51}
52
[email protected]b9a0b1b32009-03-30 23:09:3753// Static
54std::string WebClipboardImpl::URLToImageMarkup(const WebURL& url,
55 const WebString& title) {
[email protected]c62ce3e2009-02-26 00:15:2056 std::string markup("<img src=\"");
57 markup.append(url.spec());
58 markup.append("\"");
59 if (!title.isEmpty()) {
60 markup.append(" alt=\"");
[email protected]a0200c52011-10-13 14:19:2761 markup.append(net::EscapeForHTML(UTF16ToUTF8(title)));
[email protected]c62ce3e2009-02-26 00:15:2062 markup.append("\"");
63 }
64 markup.append("/>");
65 return markup;
66}
67
[email protected]0de5d8602011-11-22 03:48:5268WebClipboardImpl::WebClipboardImpl(ClipboardClient* client)
69 : client_(client) {
70}
71
[email protected]04bf3ad2010-08-27 21:23:4872WebClipboardImpl::~WebClipboardImpl() {
73}
74
[email protected]36780a12011-11-04 18:16:4475uint64 WebClipboardImpl::getSequenceNumber() {
[email protected]9cf12c32011-11-10 19:28:0776 return sequenceNumber(BufferStandard);
77}
78
79uint64 WebClipboardImpl::sequenceNumber(Buffer buffer) {
80 ui::Clipboard::Buffer buffer_type;
81 if (!ConvertBufferType(buffer, &buffer_type))
82 return 0;
83
[email protected]0de5d8602011-11-22 03:48:5284 return client_->GetSequenceNumber(buffer_type);
[email protected]36780a12011-11-04 18:16:4485}
86
[email protected]65a6150d2009-09-08 22:16:0587bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
[email protected]2dfeaf92011-01-10 21:08:2188 ui::Clipboard::FormatType format_type;
89 ui::Clipboard::Buffer buffer_type;
[email protected]c62ce3e2009-02-26 00:15:2090
[email protected]606876c2011-03-24 17:13:3891 if (!ConvertBufferType(buffer, &buffer_type))
92 return false;
93
[email protected]c62ce3e2009-02-26 00:15:2094 switch (format) {
[email protected]606876c2011-03-24 17:13:3895 case FormatPlainText:
[email protected]0de5d8602011-11-22 03:48:5296 return client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]606876c2011-03-24 17:13:3897 buffer_type) ||
[email protected]0de5d8602011-11-22 03:48:5298 client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]606876c2011-03-24 17:13:3899 buffer_type);
[email protected]c62ce3e2009-02-26 00:15:20100 case FormatHTML:
[email protected]2dfeaf92011-01-10 21:08:21101 format_type = ui::Clipboard::GetHtmlFormatType();
[email protected]c62ce3e2009-02-26 00:15:20102 break;
103 case FormatSmartPaste:
[email protected]2dfeaf92011-01-10 21:08:21104 format_type = ui::Clipboard::GetWebKitSmartPasteFormatType();
[email protected]c62ce3e2009-02-26 00:15:20105 break;
106 case FormatBookmark:
107#if defined(OS_WIN) || defined(OS_MACOSX)
[email protected]2dfeaf92011-01-10 21:08:21108 format_type = ui::Clipboard::GetUrlWFormatType();
[email protected]c62ce3e2009-02-26 00:15:20109 break;
110#endif
111 default:
112 NOTREACHED();
113 return false;
114 }
115
[email protected]0de5d8602011-11-22 03:48:52116 return client_->IsFormatAvailable(format_type, buffer_type);
[email protected]c62ce3e2009-02-26 00:15:20117}
118
[email protected]36780a12011-11-04 18:16:44119WebVector<WebString> WebClipboardImpl::readAvailableTypes(
120 Buffer buffer, bool* contains_filenames) {
121 ui::Clipboard::Buffer buffer_type;
122 std::vector<string16> types;
123 if (ConvertBufferType(buffer, &buffer_type)) {
[email protected]0de5d8602011-11-22 03:48:52124 client_->ReadAvailableTypes(buffer_type, &types, contains_filenames);
[email protected]36780a12011-11-04 18:16:44125 }
126 return types;
127}
128
[email protected]65a6150d2009-09-08 22:16:05129WebString WebClipboardImpl::readPlainText(Buffer buffer) {
[email protected]2dfeaf92011-01-10 21:08:21130 ui::Clipboard::Buffer buffer_type;
[email protected]65a6150d2009-09-08 22:16:05131 if (!ConvertBufferType(buffer, &buffer_type))
132 return WebString();
133
[email protected]0de5d8602011-11-22 03:48:52134 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
[email protected]65a6150d2009-09-08 22:16:05135 buffer_type)) {
[email protected]3a2a5d22009-03-04 03:36:36136 string16 text;
[email protected]0de5d8602011-11-22 03:48:52137 client_->ReadText(buffer_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20138 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36139 return text;
[email protected]c62ce3e2009-02-26 00:15:20140 }
141
[email protected]0de5d8602011-11-22 03:48:52142 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
[email protected]65a6150d2009-09-08 22:16:05143 buffer_type)) {
[email protected]c62ce3e2009-02-26 00:15:20144 std::string text;
[email protected]0de5d8602011-11-22 03:48:52145 client_->ReadAsciiText(buffer_type, &text);
[email protected]c62ce3e2009-02-26 00:15:20146 if (!text.empty())
[email protected]3a2a5d22009-03-04 03:36:36147 return ASCIIToUTF16(text);
[email protected]c62ce3e2009-02-26 00:15:20148 }
149
150 return WebString();
151}
152
[email protected]a96790b2011-10-06 22:24:10153WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url,
154 unsigned* fragment_start,
155 unsigned* fragment_end) {
156 ui::Clipboard::Buffer buffer_type;
157 if (!ConvertBufferType(buffer, &buffer_type))
158 return WebString();
159
160 string16 html_stdstr;
161 GURL gurl;
[email protected]0de5d8602011-11-22 03:48:52162 client_->ReadHTML(buffer_type, &html_stdstr, &gurl,
[email protected]a96790b2011-10-06 22:24:10163 static_cast<uint32*>(fragment_start),
164 static_cast<uint32*>(fragment_end));
[email protected]c62ce3e2009-02-26 00:15:20165 *source_url = gurl;
[email protected]3a2a5d22009-03-04 03:36:36166 return html_stdstr;
[email protected]c62ce3e2009-02-26 00:15:20167}
168
[email protected]3d4a6912011-03-15 20:56:19169WebData WebClipboardImpl::readImage(Buffer buffer) {
170 ui::Clipboard::Buffer buffer_type;
171 if (!ConvertBufferType(buffer, &buffer_type))
172 return WebData();
173
174 std::string png_data;
[email protected]0de5d8602011-11-22 03:48:52175 client_->ReadImage(buffer_type, &png_data);
[email protected]3d4a6912011-03-15 20:56:19176 return WebData(png_data);
177}
178
[email protected]c6562f42011-12-04 06:19:37179WebString WebClipboardImpl::readCustomData(Buffer buffer,
180 const WebString& type) {
181 ui::Clipboard::Buffer buffer_type;
182 if (!ConvertBufferType(buffer, &buffer_type))
183 return WebString();
184
185 string16 data;
186 client_->ReadCustomData(buffer_type, type, &data);
187 return data;
188}
189
[email protected]c62ce3e2009-02-26 00:15:20190void WebClipboardImpl::writeHTML(
191 const WebString& html_text, const WebURL& source_url,
192 const WebString& plain_text, bool write_smart_paste) {
[email protected]0de5d8602011-11-22 03:48:52193 ScopedClipboardWriterGlue scw(client_);
[email protected]3a2a5d22009-03-04 03:36:36194 scw.WriteHTML(html_text, source_url.spec());
195 scw.WriteText(plain_text);
[email protected]c62ce3e2009-02-26 00:15:20196
197 if (write_smart_paste)
198 scw.WriteWebSmartPaste();
199}
200
[email protected]8c95a752009-09-25 10:54:22201void WebClipboardImpl::writePlainText(const WebString& plain_text) {
[email protected]0de5d8602011-11-22 03:48:52202 ScopedClipboardWriterGlue scw(client_);
[email protected]8c95a752009-09-25 10:54:22203 scw.WriteText(plain_text);
204}
205
[email protected]c62ce3e2009-02-26 00:15:20206void WebClipboardImpl::writeURL(const WebURL& url, const WebString& title) {
[email protected]0de5d8602011-11-22 03:48:52207 ScopedClipboardWriterGlue scw(client_);
[email protected]c62ce3e2009-02-26 00:15:20208
[email protected]3a2a5d22009-03-04 03:36:36209 scw.WriteBookmark(title, url.spec());
210 scw.WriteHTML(UTF8ToUTF16(URLToMarkup(url, title)), "");
[email protected]39a749c2011-01-28 02:40:46211 scw.WriteText(UTF8ToUTF16(std::string(url.spec())));
[email protected]c62ce3e2009-02-26 00:15:20212}
213
214void WebClipboardImpl::writeImage(
215 const WebImage& image, const WebURL& url, const WebString& title) {
[email protected]0de5d8602011-11-22 03:48:52216 ScopedClipboardWriterGlue scw(client_);
[email protected]c62ce3e2009-02-26 00:15:20217
[email protected]8973f522009-07-03 05:58:45218 if (!image.isNull()) {
219#if WEBKIT_USING_SKIA
220 const SkBitmap& bitmap = image.getSkBitmap();
221#elif WEBKIT_USING_CG
222 const SkBitmap& bitmap = gfx::CGImageToSkBitmap(image.getCGImageRef());
[email protected]c62ce3e2009-02-26 00:15:20223#endif
[email protected]8973f522009-07-03 05:58:45224 SkAutoLockPixels locked(bitmap);
225 scw.WriteBitmapFromPixels(bitmap.getPixels(), image.size());
226 }
[email protected]c62ce3e2009-02-26 00:15:20227
[email protected]59d9aacf2009-11-30 22:59:25228 if (!url.isEmpty()) {
229 scw.WriteBookmark(title, url.spec());
[email protected]09303232011-06-09 19:28:31230#if !defined(OS_MACOSX)
231 // When writing the image, we also write the image markup so that pasting
232 // into rich text editors, such as Gmail, reveals the image. We also don't
233 // want to call writeText(), since some applications (WordPad) don't pick
234 // the image if there is also a text format on the clipboard.
235 // We also don't want to write HTML on a Mac, since Mail.app prefers to use
236 // the image markup over attaching the actual image. See
237 // http://crbug.com/33016 for details.
[email protected]59d9aacf2009-11-30 22:59:25238 scw.WriteHTML(UTF8ToUTF16(URLToImageMarkup(url, title)), "");
[email protected]09303232011-06-09 19:28:31239#endif
[email protected]59d9aacf2009-11-30 22:59:25240 }
[email protected]c62ce3e2009-02-26 00:15:20241}
242
[email protected]3f0318292011-11-18 21:49:00243void WebClipboardImpl::writeDataObject(const WebDragData& data) {
244 // TODO(dcheng): This actually results in a double clear of the clipboard.
245 // Once in WebKit, and once here when the clipboard writer goes out of scope.
246 // The same is true of the other WebClipboard::write* methods.
[email protected]0de5d8602011-11-22 03:48:52247 ScopedClipboardWriterGlue scw(client_);
[email protected]3f0318292011-11-18 21:49:00248
[email protected]2ffbb482011-12-05 23:41:17249 WebDropData data_object(data);
[email protected]3f0318292011-11-18 21:49:00250 // TODO(dcheng): Properly support text/uri-list here.
[email protected]2ffbb482011-12-05 23:41:17251 scw.WriteText(data_object.plain_text);
252 scw.WriteHTML(data_object.text_html, "");
253 Pickle pickle;
254 ui::WriteCustomDataToPickle(data_object.custom_data, &pickle);
255 scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType());
[email protected]3f0318292011-11-18 21:49:00256}
257
[email protected]65a6150d2009-09-08 22:16:05258bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
[email protected]2dfeaf92011-01-10 21:08:21259 ui::Clipboard::Buffer* result) {
[email protected]65a6150d2009-09-08 22:16:05260 switch (buffer) {
261 case BufferStandard:
[email protected]2dfeaf92011-01-10 21:08:21262 *result = ui::Clipboard::BUFFER_STANDARD;
[email protected]65a6150d2009-09-08 22:16:05263 break;
264 case BufferSelection:
[email protected]c2273e82011-11-14 18:51:25265#if defined(USE_X11) && !defined(USE_AURA)
[email protected]2dfeaf92011-01-10 21:08:21266 *result = ui::Clipboard::BUFFER_SELECTION;
[email protected]65a6150d2009-09-08 22:16:05267 break;
268#endif
269 default:
270 NOTREACHED();
271 return false;
272 }
273 return true;
274}
275
[email protected]c62ce3e2009-02-26 00:15:20276} // namespace webkit_glue