1 // 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.
4
5 #include "webkit/glue/webclipboard_impl.h"
6
7 #include "base/logging.h"
8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h"
10 #include "googleurl/src/gurl.h"
11 #include "net/base/escape.h"
12 #include "third_party/skia/include/core/SkBitmap.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebData.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebImage.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
19 #include "ui/base/clipboard/clipboard.h"
20 #include "webkit/glue/scoped_clipboard_writer_glue.h"
21 #include "webkit/glue/webkit_glue.h"
22
23 #if WEBKIT_USING_CG
24 #include "skia/ext/skia_utils_mac.h"
25 #endif
26
27 using WebKit::WebClipboard;
28 using WebKit::WebData;
29 using WebKit::WebImage;
30 using WebKit::WebString;
31 using WebKit::WebURL;
32 using WebKit::WebVector;
33
34 namespace webkit_glue {
35
36 // Static
URLToMarkup(const WebURL & url,const WebString & title)37 std::string WebClipboardImpl::URLToMarkup(const WebURL& url,
38 const WebString& title) {
39 std::string markup("<a href=\"");
40 markup.append(url.spec());
41 markup.append("\">");
42 // TODO(darin): HTML escape this
43 markup.append(EscapeForHTML(UTF16ToUTF8(title)));
44 markup.append("</a>");
45 return markup;
46 }
47
48 // Static
URLToImageMarkup(const WebURL & url,const WebString & title)49 std::string WebClipboardImpl::URLToImageMarkup(const WebURL& url,
50 const WebString& title) {
51 std::string markup("<img src=\"");
52 markup.append(url.spec());
53 markup.append("\"");
54 if (!title.isEmpty()) {
55 markup.append(" alt=\"");
56 markup.append(EscapeForHTML(UTF16ToUTF8(title)));
57 markup.append("\"");
58 }
59 markup.append("/>");
60 return markup;
61 }
62
~WebClipboardImpl()63 WebClipboardImpl::~WebClipboardImpl() {
64 }
65
isFormatAvailable(Format format,Buffer buffer)66 bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
67 ui::Clipboard::FormatType format_type;
68 ui::Clipboard::Buffer buffer_type;
69
70 if (!ConvertBufferType(buffer, &buffer_type))
71 return false;
72
73 switch (format) {
74 case FormatPlainText:
75 return ClipboardIsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
76 buffer_type) ||
77 ClipboardIsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
78 buffer_type);
79 case FormatHTML:
80 format_type = ui::Clipboard::GetHtmlFormatType();
81 break;
82 case FormatSmartPaste:
83 format_type = ui::Clipboard::GetWebKitSmartPasteFormatType();
84 break;
85 case FormatBookmark:
86 #if defined(OS_WIN) || defined(OS_MACOSX)
87 format_type = ui::Clipboard::GetUrlWFormatType();
88 break;
89 #endif
90 default:
91 NOTREACHED();
92 return false;
93 }
94
95 return ClipboardIsFormatAvailable(format_type, buffer_type);
96 }
97
readPlainText(Buffer buffer)98 WebString WebClipboardImpl::readPlainText(Buffer buffer) {
99 ui::Clipboard::Buffer buffer_type;
100 if (!ConvertBufferType(buffer, &buffer_type))
101 return WebString();
102
103 if (ClipboardIsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
104 buffer_type)) {
105 string16 text;
106 ClipboardReadText(buffer_type, &text);
107 if (!text.empty())
108 return text;
109 }
110
111 if (ClipboardIsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
112 buffer_type)) {
113 std::string text;
114 ClipboardReadAsciiText(buffer_type, &text);
115 if (!text.empty())
116 return ASCIIToUTF16(text);
117 }
118
119 return WebString();
120 }
121
readHTML(Buffer buffer,WebURL * source_url)122 WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url) {
123 ui::Clipboard::Buffer buffer_type;
124 if (!ConvertBufferType(buffer, &buffer_type))
125 return WebString();
126
127 string16 html_stdstr;
128 GURL gurl;
129 ClipboardReadHTML(buffer_type, &html_stdstr, &gurl);
130 *source_url = gurl;
131 return html_stdstr;
132 }
133
readImage(Buffer buffer)134 WebData WebClipboardImpl::readImage(Buffer buffer) {
135 ui::Clipboard::Buffer buffer_type;
136 if (!ConvertBufferType(buffer, &buffer_type))
137 return WebData();
138
139 std::string png_data;
140 ClipboardReadImage(buffer_type, &png_data);
141 return WebData(png_data);
142 }
143
writeHTML(const WebString & html_text,const WebURL & source_url,const WebString & plain_text,bool write_smart_paste)144 void WebClipboardImpl::writeHTML(
145 const WebString& html_text, const WebURL& source_url,
146 const WebString& plain_text, bool write_smart_paste) {
147 ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
148 scw.WriteHTML(html_text, source_url.spec());
149 scw.WriteText(plain_text);
150
151 if (write_smart_paste)
152 scw.WriteWebSmartPaste();
153 }
154
writePlainText(const WebString & plain_text)155 void WebClipboardImpl::writePlainText(const WebString& plain_text) {
156 ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
157 scw.WriteText(plain_text);
158 }
159
writeURL(const WebURL & url,const WebString & title)160 void WebClipboardImpl::writeURL(const WebURL& url, const WebString& title) {
161 ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
162
163 scw.WriteBookmark(title, url.spec());
164 scw.WriteHTML(UTF8ToUTF16(URLToMarkup(url, title)), "");
165 scw.WriteText(UTF8ToUTF16(std::string(url.spec())));
166 }
167
writeImage(const WebImage & image,const WebURL & url,const WebString & title)168 void WebClipboardImpl::writeImage(
169 const WebImage& image, const WebURL& url, const WebString& title) {
170 ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
171
172 if (!image.isNull()) {
173 #if WEBKIT_USING_SKIA
174 const SkBitmap& bitmap = image.getSkBitmap();
175 #elif WEBKIT_USING_CG
176 const SkBitmap& bitmap = gfx::CGImageToSkBitmap(image.getCGImageRef());
177 #endif
178 SkAutoLockPixels locked(bitmap);
179 scw.WriteBitmapFromPixels(bitmap.getPixels(), image.size());
180 }
181
182 // When writing the image, we also write the image markup so that pasting
183 // into rich text editors, such as Gmail, reveals the image. We also don't
184 // want to call writeText(), since some applications (WordPad) don't pick the
185 // image if there is also a text format on the clipboard.
186 if (!url.isEmpty()) {
187 scw.WriteBookmark(title, url.spec());
188 scw.WriteHTML(UTF8ToUTF16(URLToImageMarkup(url, title)), "");
189 }
190 }
191
writeData(const WebString & type,const WebString & data,const WebString & metadata)192 void WebClipboardImpl::writeData(const WebString& type,
193 const WebString& data,
194 const WebString& metadata) {
195 // TODO(dcheng): Implement this stub.
196 }
197
readAvailableTypes(Buffer buffer,bool * contains_filenames)198 WebVector<WebString> WebClipboardImpl::readAvailableTypes(
199 Buffer buffer, bool* contains_filenames) {
200 ui::Clipboard::Buffer buffer_type;
201 std::vector<string16> types;
202 if (ConvertBufferType(buffer, &buffer_type)) {
203 ClipboardReadAvailableTypes(buffer_type, &types, contains_filenames);
204 }
205 return types;
206 }
207
readData(Buffer buffer,const WebString & type,WebString * data,WebString * metadata)208 bool WebClipboardImpl::readData(Buffer buffer, const WebString& type,
209 WebString* data, WebString* metadata) {
210 ui::Clipboard::Buffer buffer_type;
211 if (!ConvertBufferType(buffer, &buffer_type))
212 return false;
213
214 string16 data_out;
215 string16 metadata_out;
216 bool result = ClipboardReadData(buffer_type, type, &data_out, &metadata_out);
217 if (result) {
218 *data = data_out;
219 *metadata = metadata_out;
220 }
221 return result;
222 }
223
readFilenames(Buffer buffer)224 WebVector<WebString> WebClipboardImpl::readFilenames(Buffer buffer) {
225 ui::Clipboard::Buffer buffer_type;
226 std::vector<string16> filenames;
227 if (ConvertBufferType(buffer, &buffer_type)) {
228 ClipboardReadFilenames(buffer_type, &filenames);
229 }
230 return filenames;
231 }
232
ConvertBufferType(Buffer buffer,ui::Clipboard::Buffer * result)233 bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
234 ui::Clipboard::Buffer* result) {
235 switch (buffer) {
236 case BufferStandard:
237 *result = ui::Clipboard::BUFFER_STANDARD;
238 break;
239 case BufferDrag:
240 *result = ui::Clipboard::BUFFER_DRAG;
241 case BufferSelection:
242 #if defined(USE_X11)
243 *result = ui::Clipboard::BUFFER_SELECTION;
244 break;
245 #endif
246 default:
247 NOTREACHED();
248 return false;
249 }
250 return true;
251 }
252
253 } // namespace webkit_glue
254