| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/renderer/webclipboard_impl.h" |
| |
| #include "base/logging.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "build/build_config.h" |
| #include "content/common/clipboard_format.h" |
| #include "content/public/common/drop_data.h" |
| #include "content/renderer/clipboard_utils.h" |
| #include "content/renderer/drop_data_builder.h" |
| #include "content/renderer/renderer_clipboard_delegate.h" |
| #include "third_party/WebKit/public/platform/WebDragData.h" |
| #include "third_party/WebKit/public/platform/WebImage.h" |
| #include "third_party/WebKit/public/platform/WebSize.h" |
| #include "third_party/WebKit/public/platform/WebString.h" |
| #include "third_party/WebKit/public/platform/WebURL.h" |
| #include "third_party/WebKit/public/platform/WebVector.h" |
| #include "url/gurl.h" |
| |
| using blink::WebBlobInfo; |
| using blink::WebClipboard; |
| using blink::WebDragData; |
| using blink::WebImage; |
| using blink::WebString; |
| using blink::WebURL; |
| using blink::WebVector; |
| |
| namespace content { |
| |
| WebClipboardImpl::WebClipboardImpl(RendererClipboardDelegate* delegate) |
| : delegate_(delegate) { |
| DCHECK(delegate); |
| } |
| |
| WebClipboardImpl::~WebClipboardImpl() { |
| } |
| |
| uint64_t WebClipboardImpl::sequenceNumber(Buffer buffer) { |
| ui::ClipboardType clipboard_type; |
| if (!ConvertBufferType(buffer, &clipboard_type)) |
| return 0; |
| |
| return delegate_->GetSequenceNumber(clipboard_type); |
| } |
| |
| bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) { |
| ui::ClipboardType clipboard_type = ui::CLIPBOARD_TYPE_COPY_PASTE; |
| |
| if (!ConvertBufferType(buffer, &clipboard_type)) |
| return false; |
| |
| switch (format) { |
| case FormatPlainText: |
| return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_PLAINTEXT, |
| clipboard_type); |
| case FormatHTML: |
| return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_HTML, |
| clipboard_type); |
| case FormatSmartPaste: |
| return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_SMART_PASTE, |
| clipboard_type); |
| case FormatBookmark: |
| return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_BOOKMARK, |
| clipboard_type); |
| default: |
| NOTREACHED(); |
| } |
| |
| return false; |
| } |
| |
| WebVector<WebString> WebClipboardImpl::readAvailableTypes( |
| Buffer buffer, bool* contains_filenames) { |
| ui::ClipboardType clipboard_type; |
| std::vector<base::string16> types; |
| if (ConvertBufferType(buffer, &clipboard_type)) { |
| delegate_->ReadAvailableTypes(clipboard_type, &types, contains_filenames); |
| } |
| return types; |
| } |
| |
| WebString WebClipboardImpl::readPlainText(Buffer buffer) { |
| ui::ClipboardType clipboard_type; |
| if (!ConvertBufferType(buffer, &clipboard_type)) |
| return WebString(); |
| |
| base::string16 text; |
| delegate_->ReadText(clipboard_type, &text); |
| return text; |
| } |
| |
| WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url, |
| unsigned* fragment_start, |
| unsigned* fragment_end) { |
| ui::ClipboardType clipboard_type; |
| if (!ConvertBufferType(buffer, &clipboard_type)) |
| return WebString(); |
| |
| base::string16 html_stdstr; |
| GURL gurl; |
| delegate_->ReadHTML(clipboard_type, &html_stdstr, &gurl, |
| static_cast<uint32_t*>(fragment_start), |
| static_cast<uint32_t*>(fragment_end)); |
| *source_url = gurl; |
| return html_stdstr; |
| } |
| |
| WebString WebClipboardImpl::readRTF(Buffer buffer) { |
| ui::ClipboardType clipboard_type; |
| if (!ConvertBufferType(buffer, &clipboard_type)) |
| return WebString(); |
| |
| std::string rtf; |
| delegate_->ReadRTF(clipboard_type, &rtf); |
| return WebString::fromLatin1(rtf); |
| } |
| |
| WebBlobInfo WebClipboardImpl::readImage(Buffer buffer) { |
| ui::ClipboardType clipboard_type; |
| if (!ConvertBufferType(buffer, &clipboard_type)) |
| return WebBlobInfo(); |
| |
| std::string blob_uuid; |
| std::string type; |
| int64_t size; |
| delegate_->ReadImage(clipboard_type, &blob_uuid, &type, &size); |
| if (size < 0) |
| return WebBlobInfo(); |
| return WebBlobInfo(WebString::fromASCII(blob_uuid), WebString::fromUTF8(type), |
| size); |
| } |
| |
| WebString WebClipboardImpl::readCustomData(Buffer buffer, |
| const WebString& type) { |
| ui::ClipboardType clipboard_type; |
| if (!ConvertBufferType(buffer, &clipboard_type)) |
| return WebString(); |
| |
| base::string16 data; |
| delegate_->ReadCustomData(clipboard_type, type, &data); |
| return data; |
| } |
| |
| void WebClipboardImpl::writePlainText(const WebString& plain_text) { |
| delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text); |
| delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE); |
| } |
| |
| void WebClipboardImpl::writeHTML( |
| const WebString& html_text, const WebURL& source_url, |
| const WebString& plain_text, bool write_smart_paste) { |
| delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE, html_text, source_url); |
| delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text); |
| |
| if (write_smart_paste) |
| delegate_->WriteSmartPasteMarker(ui::CLIPBOARD_TYPE_COPY_PASTE); |
| delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE); |
| } |
| |
| void WebClipboardImpl::writeImage(const WebImage& image, |
| const WebURL& url, |
| const WebString& title) { |
| DCHECK(!image.isNull()); |
| const SkBitmap& bitmap = image.getSkBitmap(); |
| if (!delegate_->WriteImage(ui::CLIPBOARD_TYPE_COPY_PASTE, bitmap)) |
| return; |
| |
| if (!url.isEmpty()) { |
| delegate_->WriteBookmark(ui::CLIPBOARD_TYPE_COPY_PASTE, url, title); |
| #if !defined(OS_MACOSX) |
| // When writing the image, we also write the image markup so that pasting |
| // into rich text editors, such as Gmail, reveals the image. We also don't |
| // want to call writeText(), since some applications (WordPad) don't pick |
| // the image if there is also a text format on the clipboard. |
| // We also don't want to write HTML on a Mac, since Mail.app prefers to use |
| // the image markup over attaching the actual image. See |
| // http://crbug.com/33016 for details. |
| delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE, |
| base::UTF8ToUTF16(URLToImageMarkup(url, title)), |
| GURL()); |
| #endif |
| } |
| delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE); |
| } |
| |
| void WebClipboardImpl::writeDataObject(const WebDragData& data) { |
| const DropData& data_object = DropDataBuilder::Build(data); |
| // TODO(dcheng): Properly support text/uri-list here. |
| // Avoid calling the WriteFoo functions if there is no data associated with a |
| // type. This prevents stomping on clipboard contents that might have been |
| // written by extension functions such as chrome.bookmarkManagerPrivate.copy. |
| if (!data_object.text.is_null()) |
| delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, |
| data_object.text.string()); |
| if (!data_object.html.is_null()) |
| delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE, |
| data_object.html.string(), GURL()); |
| if (!data_object.custom_data.empty()) |
| delegate_->WriteCustomData(ui::CLIPBOARD_TYPE_COPY_PASTE, |
| data_object.custom_data); |
| delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE); |
| } |
| |
| bool WebClipboardImpl::ConvertBufferType(Buffer buffer, |
| ui::ClipboardType* result) { |
| *result = ui::CLIPBOARD_TYPE_COPY_PASTE; |
| switch (buffer) { |
| case BufferStandard: |
| break; |
| case BufferSelection: |
| #if defined(USE_X11) && !defined(OS_CHROMEOS) |
| *result = ui::CLIPBOARD_TYPE_SELECTION; |
| break; |
| #else |
| // Chrome OS and non-X11 unix builds do not support |
| // the X selection clipboad. |
| // TODO: remove the need for this case, see http://crbug.com/361753 |
| return false; |
| #endif |
| default: |
| NOTREACHED(); |
| return false; |
| } |
| return true; |
| } |
| |
| } // namespace content |