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 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 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 63 WebClipboardImpl::~WebClipboardImpl() { 64 } 65 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 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 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 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 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 155 void WebClipboardImpl::writePlainText(const WebString& plain_text) { 156 ScopedClipboardWriterGlue scw(ClipboardGetClipboard()); 157 scw.WriteText(plain_text); 158 } 159 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 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 192 void WebClipboardImpl::writeData(const WebString& type, 193 const WebString& data, 194 const WebString& metadata) { 195 // TODO(dcheng): Implement this stub. 196 } 197 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 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 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 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