webclipboard_impl.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
1// Copyright (c) 2013 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 "content/renderer/webclipboard_impl.h" 6 7#include "base/logging.h" 8#include "base/pickle.h" 9#include "base/strings/string_util.h" 10#include "base/strings/utf_string_conversions.h" 11#include "content/public/common/drop_data.h" 12#include "content/renderer/clipboard_utils.h" 13#include "content/renderer/drop_data_builder.h" 14#include "content/renderer/scoped_clipboard_writer_glue.h" 15#include "third_party/WebKit/public/platform/WebData.h" 16#include "third_party/WebKit/public/platform/WebDragData.h" 17#include "third_party/WebKit/public/platform/WebImage.h" 18#include "third_party/WebKit/public/platform/WebSize.h" 19#include "third_party/WebKit/public/platform/WebString.h" 20#include "third_party/WebKit/public/platform/WebURL.h" 21#include "third_party/WebKit/public/platform/WebVector.h" 22#include "third_party/skia/include/core/SkBitmap.h" 23#include "ui/base/clipboard/clipboard.h" 24#include "ui/base/clipboard/custom_data_helper.h" 25#include "url/gurl.h" 26#include "webkit/glue/webkit_glue.h" 27 28using WebKit::WebClipboard; 29using WebKit::WebData; 30using WebKit::WebDragData; 31using WebKit::WebImage; 32using WebKit::WebString; 33using WebKit::WebURL; 34using WebKit::WebVector; 35 36namespace content { 37 38WebClipboardImpl::WebClipboardImpl(ClipboardClient* client) 39 : client_(client) { 40} 41 42WebClipboardImpl::~WebClipboardImpl() { 43} 44 45uint64 WebClipboardImpl::sequenceNumber(Buffer buffer) { 46 ui::ClipboardType clipboard_type; 47 if (!ConvertBufferType(buffer, &clipboard_type)) 48 return 0; 49 50 return client_->GetSequenceNumber(clipboard_type); 51} 52 53bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) { 54 ui::ClipboardType clipboard_type = ui::CLIPBOARD_TYPE_COPY_PASTE; 55 56 if (!ConvertBufferType(buffer, &clipboard_type)) 57 return false; 58 59 switch (format) { 60 case FormatPlainText: 61 return client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), 62 clipboard_type) || 63 client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), 64 clipboard_type); 65 case FormatHTML: 66 return client_->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(), 67 clipboard_type); 68 case FormatSmartPaste: 69 return client_->IsFormatAvailable( 70 ui::Clipboard::GetWebKitSmartPasteFormatType(), clipboard_type); 71 case FormatBookmark: 72#if defined(OS_WIN) || defined(OS_MACOSX) 73 return client_->IsFormatAvailable(ui::Clipboard::GetUrlWFormatType(), 74 clipboard_type); 75#endif 76 default: 77 NOTREACHED(); 78 } 79 80 return false; 81} 82 83WebVector<WebString> WebClipboardImpl::readAvailableTypes( 84 Buffer buffer, bool* contains_filenames) { 85 ui::ClipboardType clipboard_type; 86 std::vector<base::string16> types; 87 if (ConvertBufferType(buffer, &clipboard_type)) { 88 client_->ReadAvailableTypes(clipboard_type, &types, contains_filenames); 89 } 90 return types; 91} 92 93WebString WebClipboardImpl::readPlainText(Buffer buffer) { 94 ui::ClipboardType clipboard_type; 95 if (!ConvertBufferType(buffer, &clipboard_type)) 96 return WebString(); 97 98 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), 99 clipboard_type)) { 100 base::string16 text; 101 client_->ReadText(clipboard_type, &text); 102 if (!text.empty()) 103 return text; 104 } 105 106 if (client_->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), 107 clipboard_type)) { 108 std::string text; 109 client_->ReadAsciiText(clipboard_type, &text); 110 if (!text.empty()) 111 return ASCIIToUTF16(text); 112 } 113 114 return WebString(); 115} 116 117WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url, 118 unsigned* fragment_start, 119 unsigned* fragment_end) { 120 ui::ClipboardType clipboard_type; 121 if (!ConvertBufferType(buffer, &clipboard_type)) 122 return WebString(); 123 124 base::string16 html_stdstr; 125 GURL gurl; 126 client_->ReadHTML(clipboard_type, &html_stdstr, &gurl, 127 static_cast<uint32*>(fragment_start), 128 static_cast<uint32*>(fragment_end)); 129 *source_url = gurl; 130 return html_stdstr; 131} 132 133WebData WebClipboardImpl::readImage(Buffer buffer) { 134 ui::ClipboardType clipboard_type; 135 if (!ConvertBufferType(buffer, &clipboard_type)) 136 return WebData(); 137 138 std::string png_data; 139 client_->ReadImage(clipboard_type, &png_data); 140 return WebData(png_data); 141} 142 143WebString WebClipboardImpl::readCustomData(Buffer buffer, 144 const WebString& type) { 145 ui::ClipboardType clipboard_type; 146 if (!ConvertBufferType(buffer, &clipboard_type)) 147 return WebString(); 148 149 base::string16 data; 150 client_->ReadCustomData(clipboard_type, type, &data); 151 return data; 152} 153 154void WebClipboardImpl::writePlainText(const WebString& plain_text) { 155 ScopedClipboardWriterGlue scw(client_); 156 scw.WriteText(plain_text); 157} 158 159void WebClipboardImpl::writeHTML( 160 const WebString& html_text, const WebURL& source_url, 161 const WebString& plain_text, bool write_smart_paste) { 162 ScopedClipboardWriterGlue scw(client_); 163 scw.WriteHTML(html_text, source_url.spec()); 164 scw.WriteText(plain_text); 165 166 if (write_smart_paste) 167 scw.WriteWebSmartPaste(); 168} 169 170void WebClipboardImpl::writeImage(const WebImage& image, 171 const WebURL& url, 172 const WebString& title) { 173 ScopedClipboardWriterGlue scw(client_); 174 175 if (!image.isNull()) { 176 const SkBitmap& bitmap = image.getSkBitmap(); 177 SkAutoLockPixels locked(bitmap); 178 scw.WriteBitmapFromPixels(bitmap.getPixels(), image.size()); 179 } 180 181 if (!url.isEmpty()) { 182 scw.WriteBookmark(title, url.spec()); 183#if !defined(OS_MACOSX) 184 // When writing the image, we also write the image markup so that pasting 185 // into rich text editors, such as Gmail, reveals the image. We also don't 186 // want to call writeText(), since some applications (WordPad) don't pick 187 // the image if there is also a text format on the clipboard. 188 // We also don't want to write HTML on a Mac, since Mail.app prefers to use 189 // the image markup over attaching the actual image. See 190 // http://crbug.com/33016 for details. 191 scw.WriteHTML(UTF8ToUTF16(URLToImageMarkup(url, title)), std::string()); 192#endif 193 } 194} 195 196void WebClipboardImpl::writeDataObject(const WebDragData& data) { 197 ScopedClipboardWriterGlue scw(client_); 198 199 const DropData& data_object = DropDataBuilder::Build(data); 200 // TODO(dcheng): Properly support text/uri-list here. 201 if (!data_object.text.is_null()) 202 scw.WriteText(data_object.text.string()); 203 if (!data_object.html.is_null()) 204 scw.WriteHTML(data_object.html.string(), std::string()); 205 // If there is no custom data, avoid calling WritePickledData. This ensures 206 // that ScopedClipboardWriterGlue's dtor remains a no-op if the page didn't 207 // modify the DataTransfer object, which is important to avoid stomping on 208 // any clipboard contents written by extension functions such as 209 // chrome.bookmarkManagerPrivate.copy. 210 if (!data_object.custom_data.empty()) { 211 Pickle pickle; 212 ui::WriteCustomDataToPickle(data_object.custom_data, &pickle); 213 scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType()); 214 } 215} 216 217bool WebClipboardImpl::ConvertBufferType(Buffer buffer, 218 ui::ClipboardType* result) { 219 *result = ui::CLIPBOARD_TYPE_COPY_PASTE; 220 switch (buffer) { 221 case BufferStandard: 222 break; 223 case BufferSelection: 224#if defined(USE_X11) 225#if defined(OS_CHROMEOS) 226 // Chrome OS only supports the standard clipboard, 227 // but not the X selection clipboad. 228 return false; 229#else 230 *result = ui::CLIPBOARD_TYPE_SELECTION; 231 break; 232#endif 233#endif 234 default: 235 NOTREACHED(); 236 return false; 237 } 238 return true; 239} 240 241} // namespace content 242