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 27using WebKit::WebClipboard; 28using WebKit::WebData; 29using WebKit::WebImage; 30using WebKit::WebString; 31using WebKit::WebURL; 32using WebKit::WebVector; 33 34namespace webkit_glue { 35 36// Static 37std::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 49std::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 63WebClipboardImpl::~WebClipboardImpl() { 64} 65 66bool 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 98WebString 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 122WebString 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 134WebData 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 144void 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 155void WebClipboardImpl::writePlainText(const WebString& plain_text) { 156 ScopedClipboardWriterGlue scw(ClipboardGetClipboard()); 157 scw.WriteText(plain_text); 158} 159 160void 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 168void 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 192void WebClipboardImpl::writeData(const WebString& type, 193 const WebString& data, 194 const WebString& metadata) { 195 // TODO(dcheng): Implement this stub. 196} 197 198WebVector<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 208bool 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 224WebVector<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 233bool 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