1// Copyright 2014 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 "mojo/services/html_viewer/webclipboard_impl.h" 6 7#include "base/bind.h" 8#include "mojo/services/html_viewer/blink_basic_type_converters.h" 9 10namespace mojo { 11namespace { 12 13void CopyUint64(uint64_t* output, uint64_t input) { 14 *output = input; 15} 16 17void CopyWebString(blink::WebString* output, 18 const mojo::Array<uint8_t>& input) { 19 // blink does not differentiate between the requested data type not existing 20 // and the empty string. 21 if (input.is_null()) { 22 output->reset(); 23 } else { 24 *output = blink::WebString::fromUTF8( 25 reinterpret_cast<const char*>(&input.front()), 26 input.size()); 27 } 28} 29 30void CopyURL(blink::WebURL* pageURL, 31 const mojo::Array<uint8_t>& input) { 32 if (input.is_null()) { 33 *pageURL = blink::WebURL(); 34 } else { 35 *pageURL = GURL(std::string(reinterpret_cast<const char*>(&input.front()), 36 input.size())); 37 } 38} 39 40void CopyVectorString(std::vector<std::string>* output, 41 const Array<String>& input) { 42 *output = input.To<std::vector<std::string> >(); 43} 44 45template <typename T, typename U> 46bool Contains(const std::vector<T>& v, const U& item) { 47 return std::find(v.begin(), v.end(), item) != v.end(); 48} 49 50const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste"; 51 52} // namespace 53 54WebClipboardImpl::WebClipboardImpl(ClipboardPtr clipboard) 55 : clipboard_(clipboard.Pass()) { 56} 57 58WebClipboardImpl::~WebClipboardImpl() { 59} 60 61uint64_t WebClipboardImpl::sequenceNumber(Buffer buffer) { 62 mojo::Clipboard::Type clipboard_type = ConvertBufferType(buffer); 63 64 uint64_t number = 0; 65 clipboard_->GetSequenceNumber(clipboard_type, 66 base::Bind(&CopyUint64, &number)); 67 68 // Force this to be synchronous. 69 clipboard_.WaitForIncomingMethodCall(); 70 return number; 71} 72 73bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) { 74 mojo::Clipboard::Type clipboard_type = ConvertBufferType(buffer); 75 76 std::vector<std::string> types; 77 clipboard_->GetAvailableMimeTypes( 78 clipboard_type, base::Bind(&CopyVectorString, &types)); 79 80 // Force this to be synchronous. 81 clipboard_.WaitForIncomingMethodCall(); 82 83 switch (format) { 84 case FormatPlainText: 85 return Contains(types, mojo::Clipboard::MIME_TYPE_TEXT); 86 case FormatHTML: 87 return Contains(types, mojo::Clipboard::MIME_TYPE_HTML); 88 case FormatSmartPaste: 89 return Contains(types, kMimeTypeWebkitSmartPaste); 90 case FormatBookmark: 91 // This might be difficult. 92 return false; 93 } 94 95 return false; 96} 97 98blink::WebVector<blink::WebString> WebClipboardImpl::readAvailableTypes( 99 Buffer buffer, 100 bool* containsFilenames) { 101 mojo::Clipboard::Type clipboard_type = ConvertBufferType(buffer); 102 103 std::vector<std::string> types; 104 clipboard_->GetAvailableMimeTypes( 105 clipboard_type, base::Bind(&CopyVectorString, &types)); 106 107 // Force this to be synchronous. 108 clipboard_.WaitForIncomingMethodCall(); 109 110 // AFAICT, every instance of setting containsFilenames is false. 111 *containsFilenames = false; 112 113 blink::WebVector<blink::WebString> output(types.size()); 114 for (size_t i = 0; i < types.size(); ++i) { 115 output[i] = blink::WebString::fromUTF8(types[i]); 116 } 117 118 return output; 119} 120 121blink::WebString WebClipboardImpl::readPlainText(Buffer buffer) { 122 mojo::Clipboard::Type type = ConvertBufferType(buffer); 123 124 blink::WebString text; 125 clipboard_->ReadMimeType( 126 type, mojo::Clipboard::MIME_TYPE_TEXT, base::Bind(&CopyWebString, &text)); 127 128 // Force this to be synchronous. 129 clipboard_.WaitForIncomingMethodCall(); 130 131 return text; 132} 133 134blink::WebString WebClipboardImpl::readHTML(Buffer buffer, 135 blink::WebURL* pageURL, 136 unsigned* fragmentStart, 137 unsigned* fragmentEnd) { 138 mojo::Clipboard::Type type = ConvertBufferType(buffer); 139 140 blink::WebString html; 141 clipboard_->ReadMimeType( 142 type, mojo::Clipboard::MIME_TYPE_HTML, base::Bind(&CopyWebString, &html)); 143 clipboard_.WaitForIncomingMethodCall(); 144 145 *fragmentStart = 0; 146 *fragmentEnd = static_cast<unsigned>(html.length()); 147 148 clipboard_->ReadMimeType( 149 type, mojo::Clipboard::MIME_TYPE_URL, base::Bind(&CopyURL, pageURL)); 150 clipboard_.WaitForIncomingMethodCall(); 151 152 return html; 153} 154 155blink::WebString WebClipboardImpl::readCustomData( 156 Buffer buffer, 157 const blink::WebString& mime_type) { 158 mojo::Clipboard::Type clipboard_type = ConvertBufferType(buffer); 159 160 blink::WebString data; 161 clipboard_->ReadMimeType( 162 clipboard_type, mime_type.utf8(), base::Bind(&CopyWebString, &data)); 163 164 // Force this to be synchronous. 165 clipboard_.WaitForIncomingMethodCall(); 166 167 return data; 168} 169 170void WebClipboardImpl::writePlainText(const blink::WebString& text) { 171 Array<MimeTypePairPtr> data; 172 MimeTypePairPtr text_data(MimeTypePair::New()); 173 text_data->mime_type = mojo::Clipboard::MIME_TYPE_TEXT; 174 text_data->data = Array<uint8_t>::From(text).Pass(); 175 data.push_back(text_data.Pass()); 176 177 clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE, data.Pass()); 178} 179 180void WebClipboardImpl::writeHTML(const blink::WebString& htmlText, 181 const blink::WebURL& url, 182 const blink::WebString& plainText, 183 bool writeSmartPaste) { 184 Array<MimeTypePairPtr> data; 185 MimeTypePairPtr text_data(MimeTypePair::New()); 186 text_data->mime_type = mojo::Clipboard::MIME_TYPE_TEXT; 187 text_data->data = Array<uint8_t>::From(plainText).Pass(); 188 data.push_back(text_data.Pass()); 189 190 MimeTypePairPtr html_data(MimeTypePair::New()); 191 text_data->mime_type = mojo::Clipboard::MIME_TYPE_HTML; 192 text_data->data = Array<uint8_t>::From(htmlText).Pass(); 193 data.push_back(html_data.Pass()); 194 195 MimeTypePairPtr url_data(MimeTypePair::New()); 196 url_data->mime_type = mojo::Clipboard::MIME_TYPE_URL; 197 url_data->data = Array<uint8_t>::From(url.string()).Pass(); 198 data.push_back(url_data.Pass()); 199 200 if (writeSmartPaste) { 201 MimeTypePairPtr smart_paste(MimeTypePair::New()); 202 url_data->mime_type = kMimeTypeWebkitSmartPaste; 203 url_data->data = Array<uint8_t>::From(blink::WebString()).Pass(); 204 data.push_back(smart_paste.Pass()); 205 } 206 207 clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE, data.Pass()); 208} 209 210mojo::Clipboard::Type WebClipboardImpl::ConvertBufferType(Buffer buffer) { 211 switch (buffer) { 212 case BufferStandard: 213 return mojo::Clipboard::TYPE_COPY_PASTE; 214 case BufferSelection: 215 return mojo::Clipboard::TYPE_SELECTION; 216 } 217 218 NOTREACHED(); 219 return mojo::Clipboard::TYPE_COPY_PASTE; 220} 221 222} // namespace mojo 223