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