• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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"
26 #include "url/gurl.h"
27 
28 using blink::WebClipboard;
29 using blink::WebData;
30 using blink::WebDragData;
31 using blink::WebImage;
32 using blink::WebString;
33 using blink::WebURL;
34 using blink::WebVector;
35 
36 namespace content {
37 
WebClipboardImpl(ClipboardClient * client)38 WebClipboardImpl::WebClipboardImpl(ClipboardClient* client)
39     : client_(client) {
40 }
41 
~WebClipboardImpl()42 WebClipboardImpl::~WebClipboardImpl() {
43 }
44 
sequenceNumber(Buffer buffer)45 uint64 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 
isFormatAvailable(Format format,Buffer buffer)53 bool 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(CLIPBOARD_FORMAT_PLAINTEXT,
62                                         clipboard_type);
63     case FormatHTML:
64       return client_->IsFormatAvailable(CLIPBOARD_FORMAT_HTML, clipboard_type);
65     case FormatSmartPaste:
66       return client_->IsFormatAvailable(CLIPBOARD_FORMAT_SMART_PASTE,
67                                         clipboard_type);
68     case FormatBookmark:
69       return client_->IsFormatAvailable(CLIPBOARD_FORMAT_BOOKMARK,
70                                         clipboard_type);
71     default:
72       NOTREACHED();
73   }
74 
75   return false;
76 }
77 
readAvailableTypes(Buffer buffer,bool * contains_filenames)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);
84   }
85   return types;
86 }
87 
readPlainText(Buffer buffer)88 WebString WebClipboardImpl::readPlainText(Buffer buffer) {
89   ui::ClipboardType clipboard_type;
90   if (!ConvertBufferType(buffer, &clipboard_type))
91     return WebString();
92 
93   base::string16 text;
94   client_->ReadText(clipboard_type, &text);
95   return text;
96 }
97 
readHTML(Buffer buffer,WebURL * source_url,unsigned * fragment_start,unsigned * fragment_end)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))
103     return WebString();
104 
105   base::string16 html_stdstr;
106   GURL gurl;
107   client_->ReadHTML(clipboard_type, &html_stdstr, &gurl,
108                     static_cast<uint32*>(fragment_start),
109                     static_cast<uint32*>(fragment_end));
110   *source_url = gurl;
111   return html_stdstr;
112 }
113 
readImage(Buffer buffer)114 WebData WebClipboardImpl::readImage(Buffer buffer) {
115   ui::ClipboardType clipboard_type;
116   if (!ConvertBufferType(buffer, &clipboard_type))
117     return WebData();
118 
119   std::string png_data;
120   client_->ReadImage(clipboard_type, &png_data);
121   return WebData(png_data);
122 }
123 
readCustomData(Buffer buffer,const WebString & type)124 WebString WebClipboardImpl::readCustomData(Buffer buffer,
125                                            const WebString& type) {
126   ui::ClipboardType clipboard_type;
127   if (!ConvertBufferType(buffer, &clipboard_type))
128     return WebString();
129 
130   base::string16 data;
131   client_->ReadCustomData(clipboard_type, type, &data);
132   return data;
133 }
134 
writePlainText(const WebString & plain_text)135 void WebClipboardImpl::writePlainText(const WebString& plain_text) {
136   ScopedClipboardWriterGlue scw(client_);
137   scw.WriteText(plain_text);
138 }
139 
writeHTML(const WebString & html_text,const WebURL & source_url,const WebString & plain_text,bool write_smart_paste)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);
146 
147   if (write_smart_paste)
148     scw.WriteWebSmartPaste();
149 }
150 
writeImage(const WebImage & image,const WebURL & url,const WebString & title)151 void WebClipboardImpl::writeImage(const WebImage& image,
152                                   const WebURL& url,
153                                   const WebString& title) {
154   ScopedClipboardWriterGlue scw(client_);
155 
156   if (!image.isNull()) {
157     const SkBitmap& bitmap = image.getSkBitmap();
158     // WriteBitmapFromPixels expects 32-bit data.
159     DCHECK_EQ(bitmap.colorType(), kN32_SkColorType);
160 
161     SkAutoLockPixels locked(bitmap);
162     void *pixels = bitmap.getPixels();
163     // TODO(piman): this should not be NULL, but it is. crbug.com/369621
164     if (!pixels)
165       return;
166     scw.WriteBitmapFromPixels(pixels, image.size());
167   }
168 
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)),
180                   std::string());
181 #endif
182   }
183 }
184 
writeDataObject(const WebDragData & data)185 void WebClipboardImpl::writeDataObject(const WebDragData& data) {
186   ScopedClipboardWriterGlue scw(client_);
187 
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()) {
200     Pickle pickle;
201     ui::WriteCustomDataToPickle(data_object.custom_data, &pickle);
202     scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType());
203   }
204 }
205 
ConvertBufferType(Buffer buffer,ui::ClipboardType * result)206 bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
207                                          ui::ClipboardType* result) {
208   *result = ui::CLIPBOARD_TYPE_COPY_PASTE;
209   switch (buffer) {
210     case BufferStandard:
211       break;
212     case BufferSelection:
213 #if defined(USE_X11) && !defined(OS_CHROMEOS)
214       *result = ui::CLIPBOARD_TYPE_SELECTION;
215       break;
216 #else
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
220       return false;
221 #endif
222     default:
223       NOTREACHED();
224       return false;
225   }
226   return true;
227 }
228 
229 }  // namespace content
230