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.
5 #include "content/renderer/webclipboard_impl.h"
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/common/clipboard_format.h"
12 #include "content/public/common/drop_data.h"
13 #include "content/renderer/clipboard_utils.h"
14 #include "content/renderer/drop_data_builder.h"
15 #include "content/renderer/scoped_clipboard_writer_glue.h"
16 #include "third_party/WebKit/public/platform/WebData.h"
17 #include "third_party/WebKit/public/platform/WebDragData.h"
18 #include "third_party/WebKit/public/platform/WebImage.h"
19 #include "third_party/WebKit/public/platform/WebSize.h"
20 #include "third_party/WebKit/public/platform/WebString.h"
21 #include "third_party/WebKit/public/platform/WebURL.h"
22 #include "third_party/WebKit/public/platform/WebVector.h"
23 #include "third_party/skia/include/core/SkBitmap.h"
24 #include "ui/base/clipboard/clipboard.h"
25 #include "ui/base/clipboard/custom_data_helper.h"
28 using blink::WebClipboard
;
30 using blink::WebDragData
;
31 using blink::WebImage
;
32 using blink::WebString
;
34 using blink::WebVector
;
38 WebClipboardImpl::WebClipboardImpl(ClipboardClient
* client
)
42 WebClipboardImpl::~WebClipboardImpl() {
45 uint64
WebClipboardImpl::sequenceNumber(Buffer buffer
) {
46 ui::ClipboardType clipboard_type
;
47 if (!ConvertBufferType(buffer
, &clipboard_type
))
50 return client_
->GetSequenceNumber(clipboard_type
);
53 bool WebClipboardImpl::isFormatAvailable(Format format
, Buffer buffer
) {
54 ui::ClipboardType clipboard_type
= ui::CLIPBOARD_TYPE_COPY_PASTE
;
56 if (!ConvertBufferType(buffer
, &clipboard_type
))
61 return client_
->IsFormatAvailable(CLIPBOARD_FORMAT_PLAINTEXT
,
64 return client_
->IsFormatAvailable(CLIPBOARD_FORMAT_HTML
, clipboard_type
);
65 case FormatSmartPaste
:
66 return client_
->IsFormatAvailable(CLIPBOARD_FORMAT_SMART_PASTE
,
69 return client_
->IsFormatAvailable(CLIPBOARD_FORMAT_BOOKMARK
,
78 WebVector
<WebString
> WebClipboardImpl::readAvailableTypes(
79 Buffer buffer
, bool* contains_filenames
) {
80 ui::ClipboardType clipboard_type
;
81 std::vector
<base::string16
> types
;
82 if (ConvertBufferType(buffer
, &clipboard_type
)) {
83 client_
->ReadAvailableTypes(clipboard_type
, &types
, contains_filenames
);
88 WebString
WebClipboardImpl::readPlainText(Buffer buffer
) {
89 ui::ClipboardType clipboard_type
;
90 if (!ConvertBufferType(buffer
, &clipboard_type
))
94 client_
->ReadText(clipboard_type
, &text
);
98 WebString
WebClipboardImpl::readHTML(Buffer buffer
, WebURL
* source_url
,
99 unsigned* fragment_start
,
100 unsigned* fragment_end
) {
101 ui::ClipboardType clipboard_type
;
102 if (!ConvertBufferType(buffer
, &clipboard_type
))
105 base::string16 html_stdstr
;
107 client_
->ReadHTML(clipboard_type
, &html_stdstr
, &gurl
,
108 static_cast<uint32
*>(fragment_start
),
109 static_cast<uint32
*>(fragment_end
));
114 WebData
WebClipboardImpl::readImage(Buffer buffer
) {
115 ui::ClipboardType clipboard_type
;
116 if (!ConvertBufferType(buffer
, &clipboard_type
))
119 std::string png_data
;
120 client_
->ReadImage(clipboard_type
, &png_data
);
121 return WebData(png_data
);
124 WebString
WebClipboardImpl::readCustomData(Buffer buffer
,
125 const WebString
& type
) {
126 ui::ClipboardType clipboard_type
;
127 if (!ConvertBufferType(buffer
, &clipboard_type
))
131 client_
->ReadCustomData(clipboard_type
, type
, &data
);
135 void WebClipboardImpl::writePlainText(const WebString
& plain_text
) {
136 ScopedClipboardWriterGlue
scw(client_
);
137 scw
.WriteText(plain_text
);
140 void WebClipboardImpl::writeHTML(
141 const WebString
& html_text
, const WebURL
& source_url
,
142 const WebString
& plain_text
, bool write_smart_paste
) {
143 ScopedClipboardWriterGlue
scw(client_
);
144 scw
.WriteHTML(html_text
, source_url
.spec());
145 scw
.WriteText(plain_text
);
147 if (write_smart_paste
)
148 scw
.WriteWebSmartPaste();
151 void WebClipboardImpl::writeImage(const WebImage
& image
,
153 const WebString
& title
) {
154 ScopedClipboardWriterGlue
scw(client_
);
156 if (!image
.isNull()) {
157 const SkBitmap
& bitmap
= image
.getSkBitmap();
158 // WriteBitmapFromPixels expects 32-bit data.
159 DCHECK_EQ(bitmap
.colorType(), kN32_SkColorType
);
161 SkAutoLockPixels
locked(bitmap
);
162 void *pixels
= bitmap
.getPixels();
163 // TODO(piman): this should not be NULL, but it is. crbug.com/369621
166 scw
.WriteBitmapFromPixels(pixels
, image
.size());
169 if (!url
.isEmpty()) {
170 scw
.WriteBookmark(title
, url
.spec());
171 #if !defined(OS_MACOSX)
172 // When writing the image, we also write the image markup so that pasting
173 // into rich text editors, such as Gmail, reveals the image. We also don't
174 // want to call writeText(), since some applications (WordPad) don't pick
175 // the image if there is also a text format on the clipboard.
176 // We also don't want to write HTML on a Mac, since Mail.app prefers to use
177 // the image markup over attaching the actual image. See
178 // http://crbug.com/33016 for details.
179 scw
.WriteHTML(base::UTF8ToUTF16(URLToImageMarkup(url
, title
)),
185 void WebClipboardImpl::writeDataObject(const WebDragData
& data
) {
186 ScopedClipboardWriterGlue
scw(client_
);
188 const DropData
& data_object
= DropDataBuilder::Build(data
);
189 // TODO(dcheng): Properly support text/uri-list here.
190 if (!data_object
.text
.is_null())
191 scw
.WriteText(data_object
.text
.string());
192 if (!data_object
.html
.is_null())
193 scw
.WriteHTML(data_object
.html
.string(), std::string());
194 // If there is no custom data, avoid calling WritePickledData. This ensures
195 // that ScopedClipboardWriterGlue's dtor remains a no-op if the page didn't
196 // modify the DataTransfer object, which is important to avoid stomping on
197 // any clipboard contents written by extension functions such as
198 // chrome.bookmarkManagerPrivate.copy.
199 if (!data_object
.custom_data
.empty()) {
201 ui::WriteCustomDataToPickle(data_object
.custom_data
, &pickle
);
202 scw
.WritePickledData(pickle
, ui::Clipboard::GetWebCustomDataFormatType());
206 bool WebClipboardImpl::ConvertBufferType(Buffer buffer
,
207 ui::ClipboardType
* result
) {
208 *result
= ui::CLIPBOARD_TYPE_COPY_PASTE
;
212 case BufferSelection
:
213 #if defined(USE_X11) && !defined(OS_CHROMEOS)
214 *result
= ui::CLIPBOARD_TYPE_SELECTION
;
217 // Chrome OS and non-X11 unix builds do not support
218 // the X selection clipboad.
219 // TODO: remove the need for this case, see http://crbug.com/361753
229 } // namespace content